-
-
Notifications
You must be signed in to change notification settings - Fork 673
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
✨ Add support for cascade delete relationships:
cascade_delete
, `on…
…delete`, and `passive_deletes` (#983) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>
- Loading branch information
1 parent
19c7367
commit 86ab09f
Showing
37 changed files
with
4,501 additions
and
2 deletions.
There are no files selected for viewing
1,304 changes: 1,304 additions & 0 deletions
1,304
docs/tutorial/relationship-attributes/cascade-delete-relationships.md
Large diffs are not rendered by default.
Oops, something went wrong.
Empty file.
110 changes: 110 additions & 0 deletions
110
docs_src/tutorial/relationship_attributes/cascade_delete_relationships/tutorial001.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
from typing import List, Optional | ||
|
||
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select | ||
|
||
|
||
class Team(SQLModel, table=True): | ||
id: Optional[int] = Field(default=None, primary_key=True) | ||
name: str = Field(index=True) | ||
headquarters: str | ||
|
||
heroes: List["Hero"] = Relationship(back_populates="team", cascade_delete=True) | ||
|
||
|
||
class Hero(SQLModel, table=True): | ||
id: Optional[int] = Field(default=None, primary_key=True) | ||
name: str = Field(index=True) | ||
secret_name: str | ||
age: Optional[int] = Field(default=None, index=True) | ||
|
||
team_id: Optional[int] = Field( | ||
default=None, foreign_key="team.id", ondelete="CASCADE" | ||
) | ||
team: Optional[Team] = Relationship(back_populates="heroes") | ||
|
||
|
||
sqlite_file_name = "database.db" | ||
sqlite_url = f"sqlite:///{sqlite_file_name}" | ||
|
||
engine = create_engine(sqlite_url, echo=True) | ||
|
||
|
||
def create_db_and_tables(): | ||
SQLModel.metadata.create_all(engine) | ||
|
||
|
||
def create_heroes(): | ||
with Session(engine) as session: | ||
team_preventers = Team(name="Preventers", headquarters="Sharp Tower") | ||
team_z_force = Team(name="Z-Force", headquarters="Sister Margaret's Bar") | ||
|
||
hero_deadpond = Hero( | ||
name="Deadpond", secret_name="Dive Wilson", team=team_z_force | ||
) | ||
hero_rusty_man = Hero( | ||
name="Rusty-Man", secret_name="Tommy Sharp", age=48, team=team_preventers | ||
) | ||
hero_spider_boy = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") | ||
session.add(hero_deadpond) | ||
session.add(hero_rusty_man) | ||
session.add(hero_spider_boy) | ||
session.commit() | ||
|
||
session.refresh(hero_deadpond) | ||
session.refresh(hero_rusty_man) | ||
session.refresh(hero_spider_boy) | ||
|
||
print("Created hero:", hero_deadpond) | ||
print("Created hero:", hero_rusty_man) | ||
print("Created hero:", hero_spider_boy) | ||
|
||
hero_spider_boy.team = team_preventers | ||
session.add(hero_spider_boy) | ||
session.commit() | ||
session.refresh(hero_spider_boy) | ||
print("Updated hero:", hero_spider_boy) | ||
|
||
hero_black_lion = Hero(name="Black Lion", secret_name="Trevor Challa", age=35) | ||
hero_sure_e = Hero(name="Princess Sure-E", secret_name="Sure-E") | ||
team_wakaland = Team( | ||
name="Wakaland", | ||
headquarters="Wakaland Capital City", | ||
heroes=[hero_black_lion, hero_sure_e], | ||
) | ||
session.add(team_wakaland) | ||
session.commit() | ||
session.refresh(team_wakaland) | ||
print("Team Wakaland:", team_wakaland) | ||
|
||
|
||
def delete_team(): | ||
with Session(engine) as session: | ||
statement = select(Team).where(Team.name == "Wakaland") | ||
team = session.exec(statement).one() | ||
session.delete(team) | ||
session.commit() | ||
print("Deleted team:", team) | ||
|
||
|
||
def select_deleted_heroes(): | ||
with Session(engine) as session: | ||
statement = select(Hero).where(Hero.name == "Black Lion") | ||
result = session.exec(statement) | ||
hero = result.first() | ||
print("Black Lion not found:", hero) | ||
|
||
statement = select(Hero).where(Hero.name == "Princess Sure-E") | ||
result = session.exec(statement) | ||
hero = result.first() | ||
print("Princess Sure-E not found:", hero) | ||
|
||
|
||
def main(): | ||
create_db_and_tables() | ||
create_heroes() | ||
delete_team() | ||
select_deleted_heroes() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
106 changes: 106 additions & 0 deletions
106
docs_src/tutorial/relationship_attributes/cascade_delete_relationships/tutorial001_py310.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select | ||
|
||
|
||
class Team(SQLModel, table=True): | ||
id: int | None = Field(default=None, primary_key=True) | ||
name: str = Field(index=True) | ||
headquarters: str | ||
|
||
heroes: list["Hero"] = Relationship(back_populates="team", cascade_delete=True) | ||
|
||
|
||
class Hero(SQLModel, table=True): | ||
id: int | None = Field(default=None, primary_key=True) | ||
name: str = Field(index=True) | ||
secret_name: str | ||
age: int | None = Field(default=None, index=True) | ||
|
||
team_id: int | None = Field(default=None, foreign_key="team.id", ondelete="CASCADE") | ||
team: Team | None = Relationship(back_populates="heroes") | ||
|
||
|
||
sqlite_file_name = "database.db" | ||
sqlite_url = f"sqlite:///{sqlite_file_name}" | ||
|
||
engine = create_engine(sqlite_url, echo=True) | ||
|
||
|
||
def create_db_and_tables(): | ||
SQLModel.metadata.create_all(engine) | ||
|
||
|
||
def create_heroes(): | ||
with Session(engine) as session: | ||
team_preventers = Team(name="Preventers", headquarters="Sharp Tower") | ||
team_z_force = Team(name="Z-Force", headquarters="Sister Margaret's Bar") | ||
|
||
hero_deadpond = Hero( | ||
name="Deadpond", secret_name="Dive Wilson", team=team_z_force | ||
) | ||
hero_rusty_man = Hero( | ||
name="Rusty-Man", secret_name="Tommy Sharp", age=48, team=team_preventers | ||
) | ||
hero_spider_boy = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") | ||
session.add(hero_deadpond) | ||
session.add(hero_rusty_man) | ||
session.add(hero_spider_boy) | ||
session.commit() | ||
|
||
session.refresh(hero_deadpond) | ||
session.refresh(hero_rusty_man) | ||
session.refresh(hero_spider_boy) | ||
|
||
print("Created hero:", hero_deadpond) | ||
print("Created hero:", hero_rusty_man) | ||
print("Created hero:", hero_spider_boy) | ||
|
||
hero_spider_boy.team = team_preventers | ||
session.add(hero_spider_boy) | ||
session.commit() | ||
session.refresh(hero_spider_boy) | ||
print("Updated hero:", hero_spider_boy) | ||
|
||
hero_black_lion = Hero(name="Black Lion", secret_name="Trevor Challa", age=35) | ||
hero_sure_e = Hero(name="Princess Sure-E", secret_name="Sure-E") | ||
team_wakaland = Team( | ||
name="Wakaland", | ||
headquarters="Wakaland Capital City", | ||
heroes=[hero_black_lion, hero_sure_e], | ||
) | ||
session.add(team_wakaland) | ||
session.commit() | ||
session.refresh(team_wakaland) | ||
print("Team Wakaland:", team_wakaland) | ||
|
||
|
||
def delete_team(): | ||
with Session(engine) as session: | ||
statement = select(Team).where(Team.name == "Wakaland") | ||
team = session.exec(statement).one() | ||
session.delete(team) | ||
session.commit() | ||
print("Deleted team:", team) | ||
|
||
|
||
def select_deleted_heroes(): | ||
with Session(engine) as session: | ||
statement = select(Hero).where(Hero.name == "Black Lion") | ||
result = session.exec(statement) | ||
hero = result.first() | ||
print("Black Lion not found:", hero) | ||
|
||
statement = select(Hero).where(Hero.name == "Princess Sure-E") | ||
result = session.exec(statement) | ||
hero = result.first() | ||
print("Princess Sure-E not found:", hero) | ||
|
||
|
||
def main(): | ||
create_db_and_tables() | ||
create_heroes() | ||
delete_team() | ||
select_deleted_heroes() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
110 changes: 110 additions & 0 deletions
110
docs_src/tutorial/relationship_attributes/cascade_delete_relationships/tutorial001_py39.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
from typing import Optional | ||
|
||
from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select | ||
|
||
|
||
class Team(SQLModel, table=True): | ||
id: Optional[int] = Field(default=None, primary_key=True) | ||
name: str = Field(index=True) | ||
headquarters: str | ||
|
||
heroes: list["Hero"] = Relationship(back_populates="team", cascade_delete=True) | ||
|
||
|
||
class Hero(SQLModel, table=True): | ||
id: Optional[int] = Field(default=None, primary_key=True) | ||
name: str = Field(index=True) | ||
secret_name: str | ||
age: Optional[int] = Field(default=None, index=True) | ||
|
||
team_id: Optional[int] = Field( | ||
default=None, foreign_key="team.id", ondelete="CASCADE" | ||
) | ||
team: Optional[Team] = Relationship(back_populates="heroes") | ||
|
||
|
||
sqlite_file_name = "database.db" | ||
sqlite_url = f"sqlite:///{sqlite_file_name}" | ||
|
||
engine = create_engine(sqlite_url, echo=True) | ||
|
||
|
||
def create_db_and_tables(): | ||
SQLModel.metadata.create_all(engine) | ||
|
||
|
||
def create_heroes(): | ||
with Session(engine) as session: | ||
team_preventers = Team(name="Preventers", headquarters="Sharp Tower") | ||
team_z_force = Team(name="Z-Force", headquarters="Sister Margaret's Bar") | ||
|
||
hero_deadpond = Hero( | ||
name="Deadpond", secret_name="Dive Wilson", team=team_z_force | ||
) | ||
hero_rusty_man = Hero( | ||
name="Rusty-Man", secret_name="Tommy Sharp", age=48, team=team_preventers | ||
) | ||
hero_spider_boy = Hero(name="Spider-Boy", secret_name="Pedro Parqueador") | ||
session.add(hero_deadpond) | ||
session.add(hero_rusty_man) | ||
session.add(hero_spider_boy) | ||
session.commit() | ||
|
||
session.refresh(hero_deadpond) | ||
session.refresh(hero_rusty_man) | ||
session.refresh(hero_spider_boy) | ||
|
||
print("Created hero:", hero_deadpond) | ||
print("Created hero:", hero_rusty_man) | ||
print("Created hero:", hero_spider_boy) | ||
|
||
hero_spider_boy.team = team_preventers | ||
session.add(hero_spider_boy) | ||
session.commit() | ||
session.refresh(hero_spider_boy) | ||
print("Updated hero:", hero_spider_boy) | ||
|
||
hero_black_lion = Hero(name="Black Lion", secret_name="Trevor Challa", age=35) | ||
hero_sure_e = Hero(name="Princess Sure-E", secret_name="Sure-E") | ||
team_wakaland = Team( | ||
name="Wakaland", | ||
headquarters="Wakaland Capital City", | ||
heroes=[hero_black_lion, hero_sure_e], | ||
) | ||
session.add(team_wakaland) | ||
session.commit() | ||
session.refresh(team_wakaland) | ||
print("Team Wakaland:", team_wakaland) | ||
|
||
|
||
def delete_team(): | ||
with Session(engine) as session: | ||
statement = select(Team).where(Team.name == "Wakaland") | ||
team = session.exec(statement).one() | ||
session.delete(team) | ||
session.commit() | ||
print("Deleted team:", team) | ||
|
||
|
||
def select_deleted_heroes(): | ||
with Session(engine) as session: | ||
statement = select(Hero).where(Hero.name == "Black Lion") | ||
result = session.exec(statement) | ||
hero = result.first() | ||
print("Black Lion not found:", hero) | ||
|
||
statement = select(Hero).where(Hero.name == "Princess Sure-E") | ||
result = session.exec(statement) | ||
hero = result.first() | ||
print("Princess Sure-E not found:", hero) | ||
|
||
|
||
def main(): | ||
create_db_and_tables() | ||
create_heroes() | ||
delete_team() | ||
select_deleted_heroes() | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.