]> git.ipfire.org Git - thirdparty/fastapi/sqlmodel.git/commitdiff
✨ Add source examples for docs
authorSebastián Ramírez <tiangolo@gmail.com>
Tue, 24 Aug 2021 12:50:16 +0000 (14:50 +0200)
committerSebastián Ramírez <tiangolo@gmail.com>
Tue, 24 Aug 2021 12:50:16 +0000 (14:50 +0200)
126 files changed:
docs_src/__init__.py [new file with mode: 0644]
docs_src/tutorial/__init__.py [new file with mode: 0644]
docs_src/tutorial/automatic_id_none_refresh/__init__.py [new file with mode: 0644]
docs_src/tutorial/automatic_id_none_refresh/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/automatic_id_none_refresh/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/code_structure/__init__.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial001/__init__.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial001/app.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial001/database.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial001/models.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial002/__init__.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial002/app.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial002/database.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial002/hero_model.py [new file with mode: 0644]
docs_src/tutorial/code_structure/tutorial002/team_model.py [new file with mode: 0644]
docs_src/tutorial/connect/__init__.py [new file with mode: 0644]
docs_src/tutorial/connect/create_tables/__init__.py [new file with mode: 0644]
docs_src/tutorial/connect/create_tables/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/connect/delete/__init__.py [new file with mode: 0644]
docs_src/tutorial/connect/delete/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/connect/insert/__init__.py [new file with mode: 0644]
docs_src/tutorial/connect/insert/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/connect/select/__init__.py [new file with mode: 0644]
docs_src/tutorial/connect/select/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/connect/select/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/connect/select/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/connect/select/tutorial004.py [new file with mode: 0644]
docs_src/tutorial/connect/select/tutorial005.py [new file with mode: 0644]
docs_src/tutorial/connect/update/__init__.py [new file with mode: 0644]
docs_src/tutorial/connect/update/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/create_db_and_table/__init__.py [new file with mode: 0644]
docs_src/tutorial/create_db_and_table/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/create_db_and_table/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/create_db_and_table/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/delete/__init__.py [new file with mode: 0644]
docs_src/tutorial/delete/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/delete/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/fastapi/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/main.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_002.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_003.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_004.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_005.py [new file with mode: 0644]
docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_006.py [new file with mode: 0644]
docs_src/tutorial/fastapi/delete/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/delete/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/limit_and_offset/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/limit_and_offset/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/multiple_models/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/multiple_models/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/multiple_models/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/fastapi/read_one/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/read_one/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/relationships/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/relationships/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/response_model/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/response_model/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/session_with_dependency/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/simple_hero_api/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/teams/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/teams/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/fastapi/update/__init__.py [new file with mode: 0644]
docs_src/tutorial/fastapi/update/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/insert/__init__.py [new file with mode: 0644]
docs_src/tutorial/insert/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/insert/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/insert/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/many_to_many/__init__.py [new file with mode: 0644]
docs_src/tutorial/many_to_many/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/many_to_many/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/many_to_many/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/offset_and_limit/__init__.py [new file with mode: 0644]
docs_src/tutorial/offset_and_limit/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/offset_and_limit/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/offset_and_limit/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/offset_and_limit/tutorial004.py [new file with mode: 0644]
docs_src/tutorial/one/__init__.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial004.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial005.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial006.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial007.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial008.py [new file with mode: 0644]
docs_src/tutorial/one/tutorial009.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/__init__.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/back_populates/__init__.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/back_populates/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/create_and_update_relationships/__init__.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/create_and_update_relationships/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/define_relationship_attributes/__init__.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/read_relationships/__init__.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/read_relationships/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/relationship_attributes/read_relationships/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/select/__init__.py [new file with mode: 0644]
docs_src/tutorial/select/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/select/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/select/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/select/tutorial004.py [new file with mode: 0644]
docs_src/tutorial/update/__init__.py [new file with mode: 0644]
docs_src/tutorial/update/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/update/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/update/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/update/tutorial004.py [new file with mode: 0644]
docs_src/tutorial/where/__init__.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial001.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial002.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial003.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial004.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial005.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial006.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial007.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial008.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial009.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial010.py [new file with mode: 0644]
docs_src/tutorial/where/tutorial011.py [new file with mode: 0644]

diff --git a/docs_src/__init__.py b/docs_src/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/__init__.py b/docs_src/tutorial/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/automatic_id_none_refresh/__init__.py b/docs_src/tutorial/automatic_id_none_refresh/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/automatic_id_none_refresh/tutorial001.py b/docs_src/tutorial/automatic_id_none_refresh/tutorial001.py
new file mode 100644 (file)
index 0000000..e15742f
--- /dev/null
@@ -0,0 +1,81 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    print("Before interacting with the database")
+    print("Hero 1:", hero_1)
+    print("Hero 2:", hero_2)
+    print("Hero 3:", hero_3)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        print("After adding to the session")
+        print("Hero 1:", hero_1)
+        print("Hero 2:", hero_2)
+        print("Hero 3:", hero_3)
+
+        session.commit()
+
+        print("After committing the session")
+        print("Hero 1:", hero_1)
+        print("Hero 2:", hero_2)
+        print("Hero 3:", hero_3)
+
+        print("After committing the session, show IDs")
+        print("Hero 1 ID:", hero_1.id)
+        print("Hero 2 ID:", hero_2.id)
+        print("Hero 3 ID:", hero_3.id)
+
+        print("After committing the session, show names")
+        print("Hero 1 name:", hero_1.name)
+        print("Hero 2 name:", hero_2.name)
+        print("Hero 3 name:", hero_3.name)
+
+        session.refresh(hero_1)
+        session.refresh(hero_2)
+        session.refresh(hero_3)
+
+        print("After refreshing the heroes")
+        print("Hero 1:", hero_1)
+        print("Hero 2:", hero_2)
+        print("Hero 3:", hero_3)
+
+    print("After the session closes")
+    print("Hero 1:", hero_1)
+    print("Hero 2:", hero_2)
+    print("Hero 3:", hero_3)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/automatic_id_none_refresh/tutorial002.py b/docs_src/tutorial/automatic_id_none_refresh/tutorial002.py
new file mode 100644 (file)
index 0000000..1c7cd53
--- /dev/null
@@ -0,0 +1,82 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")  # (1)
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")  # (2)
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)  # (3)
+
+    print("Before interacting with the database")  # (4)
+    print("Hero 1:", hero_1)  # (5)
+    print("Hero 2:", hero_2)  # (6)
+    print("Hero 3:", hero_3)  # (7)
+
+    with Session(engine) as session:  # (8)
+        session.add(hero_1)  # (9)
+        session.add(hero_2)  # (10)
+        session.add(hero_3)  # (11)
+
+        print("After adding to the session")  # (12)
+        print("Hero 1:", hero_1)  # (13)
+        print("Hero 2:", hero_2)  # (14)
+        print("Hero 3:", hero_3)  # (15)
+
+        session.commit()  # (16)
+
+        print("After committing the session")  # (17)
+        print("Hero 1:", hero_1)  # (18)
+        print("Hero 2:", hero_2)  # (19)
+        print("Hero 3:", hero_3)  # (20)
+
+        print("After committing the session, show IDs")  # (21)
+        print("Hero 1 ID:", hero_1.id)  # (22)
+        print("Hero 2 ID:", hero_2.id)  # (23)
+        print("Hero 3 ID:", hero_3.id)  # (24)
+
+        print("After committing the session, show names")  # (25)
+        print("Hero 1 name:", hero_1.name)  # (26)
+        print("Hero 2 name:", hero_2.name)  # (27)
+        print("Hero 3 name:", hero_3.name)  # (28)
+
+        session.refresh(hero_1)  # (29)
+        session.refresh(hero_2)  # (30)
+        session.refresh(hero_3)  # (31)
+
+        print("After refreshing the heroes")  # (32)
+        print("Hero 1:", hero_1)  # (33)
+        print("Hero 2:", hero_2)  # (34)
+        print("Hero 3:", hero_3)  # (35)
+    # (36)
+
+    print("After the session closes")  # (37)
+    print("Hero 1:", hero_1)  # (38)
+    print("Hero 2:", hero_2)  # (39)
+    print("Hero 3:", hero_3)  # (40)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/code_structure/__init__.py b/docs_src/tutorial/code_structure/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/code_structure/tutorial001/__init__.py b/docs_src/tutorial/code_structure/tutorial001/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/code_structure/tutorial001/app.py b/docs_src/tutorial/code_structure/tutorial001/app.py
new file mode 100644 (file)
index 0000000..065f8a7
--- /dev/null
@@ -0,0 +1,29 @@
+from sqlmodel import Session
+
+from .database import create_db_and_tables, engine
+from .models import Hero, Team
+
+
+def create_heroes():
+    with Session(engine) as session:
+        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
+        )
+        session.add(hero_deadpond)
+        session.commit()
+
+        session.refresh(hero_deadpond)
+
+        print("Created hero:", hero_deadpond)
+        print("Hero's team:", hero_deadpond.team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/code_structure/tutorial001/database.py b/docs_src/tutorial/code_structure/tutorial001/database.py
new file mode 100644 (file)
index 0000000..d6de16c
--- /dev/null
@@ -0,0 +1,10 @@
+from sqlmodel import SQLModel, create_engine
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+engine = create_engine(sqlite_url)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
diff --git a/docs_src/tutorial/code_structure/tutorial001/models.py b/docs_src/tutorial/code_structure/tutorial001/models.py
new file mode 100644 (file)
index 0000000..9bd1fa9
--- /dev/null
@@ -0,0 +1,21 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, SQLModel
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    team: Optional[Team] = Relationship(back_populates="heroes")
diff --git a/docs_src/tutorial/code_structure/tutorial002/__init__.py b/docs_src/tutorial/code_structure/tutorial002/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/code_structure/tutorial002/app.py b/docs_src/tutorial/code_structure/tutorial002/app.py
new file mode 100644 (file)
index 0000000..8afaee7
--- /dev/null
@@ -0,0 +1,30 @@
+from sqlmodel import Session
+
+from .database import create_db_and_tables, engine
+from .hero_model import Hero
+from .team_model import Team
+
+
+def create_heroes():
+    with Session(engine) as session:
+        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
+        )
+        session.add(hero_deadpond)
+        session.commit()
+
+        session.refresh(hero_deadpond)
+
+        print("Created hero:", hero_deadpond)
+        print("Hero's team:", hero_deadpond.team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/code_structure/tutorial002/database.py b/docs_src/tutorial/code_structure/tutorial002/database.py
new file mode 100644 (file)
index 0000000..d6de16c
--- /dev/null
@@ -0,0 +1,10 @@
+from sqlmodel import SQLModel, create_engine
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+engine = create_engine(sqlite_url)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
diff --git a/docs_src/tutorial/code_structure/tutorial002/hero_model.py b/docs_src/tutorial/code_structure/tutorial002/hero_model.py
new file mode 100644 (file)
index 0000000..84fc7f2
--- /dev/null
@@ -0,0 +1,16 @@
+from typing import TYPE_CHECKING, Optional
+
+from sqlmodel import Field, Relationship, SQLModel
+
+if TYPE_CHECKING:
+    from .team_model import Team
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    team: Optional["Team"] = Relationship(back_populates="heroes")
diff --git a/docs_src/tutorial/code_structure/tutorial002/team_model.py b/docs_src/tutorial/code_structure/tutorial002/team_model.py
new file mode 100644 (file)
index 0000000..54974a0
--- /dev/null
@@ -0,0 +1,14 @@
+from typing import TYPE_CHECKING, List, Optional
+
+from sqlmodel import Field, Relationship, SQLModel
+
+if TYPE_CHECKING:
+    from .hero_model import Hero
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
diff --git a/docs_src/tutorial/connect/__init__.py b/docs_src/tutorial/connect/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/connect/create_tables/__init__.py b/docs_src/tutorial/connect/create_tables/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/connect/create_tables/tutorial001.py b/docs_src/tutorial/connect/create_tables/tutorial001.py
new file mode 100644 (file)
index 0000000..86dcc9a
--- /dev/null
@@ -0,0 +1,36 @@
+from typing import Optional
+
+from sqlmodel import Field, SQLModel, create_engine
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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 main():
+    create_db_and_tables()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/delete/__init__.py b/docs_src/tutorial/connect/delete/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/connect/delete/tutorial001.py b/docs_src/tutorial/connect/delete/tutorial001.py
new file mode 100644 (file)
index 0000000..57bbd0e
--- /dev/null
@@ -0,0 +1,81 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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_id = team_preventers.id
+        session.add(hero_spider_boy)
+        session.commit()
+        session.refresh(hero_spider_boy)
+        print("Updated hero:", hero_spider_boy)
+
+        hero_spider_boy.team_id = None
+        session.add(hero_spider_boy)
+        session.commit()
+        session.refresh(hero_spider_boy)
+        print("No longer Preventer:", hero_spider_boy)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/insert/__init__.py b/docs_src/tutorial/connect/insert/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/connect/insert/tutorial001.py b/docs_src/tutorial/connect/insert/tutorial001.py
new file mode 100644 (file)
index 0000000..d64d37f
--- /dev/null
@@ -0,0 +1,69 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/select/__init__.py b/docs_src/tutorial/connect/select/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/connect/select/tutorial001.py b/docs_src/tutorial/connect/select/tutorial001.py
new file mode 100644 (file)
index 0000000..18c4f40
--- /dev/null
@@ -0,0 +1,78 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero, Team).where(Hero.team_id == Team.id)
+        results = session.exec(statement)
+        for hero, team in results:
+            print("Hero:", hero, "Team:", team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/select/tutorial002.py b/docs_src/tutorial/connect/select/tutorial002.py
new file mode 100644 (file)
index 0000000..f7df277
--- /dev/null
@@ -0,0 +1,78 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero, Team).join(Team)
+        results = session.exec(statement)
+        for hero, team in results:
+            print("Hero:", hero, "Team:", team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/select/tutorial003.py b/docs_src/tutorial/connect/select/tutorial003.py
new file mode 100644 (file)
index 0000000..110cace
--- /dev/null
@@ -0,0 +1,78 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero, Team).join(Team, isouter=True)
+        results = session.exec(statement)
+        for hero, team in results:
+            print("Hero:", hero, "Team:", team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/select/tutorial004.py b/docs_src/tutorial/connect/select/tutorial004.py
new file mode 100644 (file)
index 0000000..87e739a
--- /dev/null
@@ -0,0 +1,78 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).join(Team).where(Team.name == "Preventers")
+        results = session.exec(statement)
+        for hero in results:
+            print("Preventer Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/select/tutorial005.py b/docs_src/tutorial/connect/select/tutorial005.py
new file mode 100644 (file)
index 0000000..0e696d0
--- /dev/null
@@ -0,0 +1,78 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero, Team).join(Team).where(Team.name == "Preventers")
+        results = session.exec(statement)
+        for hero, team in results:
+            print("Preventer Hero:", hero, "Team:", team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/connect/update/__init__.py b/docs_src/tutorial/connect/update/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/connect/update/tutorial001.py b/docs_src/tutorial/connect/update/tutorial001.py
new file mode 100644 (file)
index 0000000..3c9726f
--- /dev/null
@@ -0,0 +1,75 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+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")
+        session.add(team_preventers)
+        session.add(team_z_force)
+        session.commit()
+
+        hero_deadpond = Hero(
+            name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            team_id=team_preventers.id,
+        )
+        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_id = team_preventers.id
+        session.add(hero_spider_boy)
+        session.commit()
+        session.refresh(hero_spider_boy)
+        print("Updated hero:", hero_spider_boy)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/create_db_and_table/__init__.py b/docs_src/tutorial/create_db_and_table/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/create_db_and_table/tutorial001.py b/docs_src/tutorial/create_db_and_table/tutorial001.py
new file mode 100644 (file)
index 0000000..cab7d9e
--- /dev/null
@@ -0,0 +1,18 @@
+from typing import Optional
+
+from sqlmodel import Field, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+engine = create_engine(sqlite_url, echo=True)
+
+SQLModel.metadata.create_all(engine)
diff --git a/docs_src/tutorial/create_db_and_table/tutorial002.py b/docs_src/tutorial/create_db_and_table/tutorial002.py
new file mode 100644 (file)
index 0000000..3297aef
--- /dev/null
@@ -0,0 +1,24 @@
+from typing import Optional
+
+from sqlmodel import Field, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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)
+
+
+if __name__ == "__main__":
+    create_db_and_tables()
diff --git a/docs_src/tutorial/create_db_and_table/tutorial003.py b/docs_src/tutorial/create_db_and_table/tutorial003.py
new file mode 100644 (file)
index 0000000..8650870
--- /dev/null
@@ -0,0 +1,24 @@
+from typing import Optional  # (1)
+
+from sqlmodel import Field, SQLModel, create_engine  # (2)
+
+
+class Hero(SQLModel, table=True):  # (3)
+    id: Optional[int] = Field(default=None, primary_key=True)  # (4)
+    name: str  # (5)
+    secret_name: str  # (6)
+    age: Optional[int] = None  # (7)
+
+
+sqlite_file_name = "database.db"  # (8)
+sqlite_url = f"sqlite:///{sqlite_file_name}"  # (9)
+
+engine = create_engine(sqlite_url, echo=True)  # (10)
+
+
+def create_db_and_tables():  # (11)
+    SQLModel.metadata.create_all(engine)  # (12)
+
+
+if __name__ == "__main__":  # (13)
+    create_db_and_tables()  # (14)
diff --git a/docs_src/tutorial/delete/__init__.py b/docs_src/tutorial/delete/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/delete/tutorial001.py b/docs_src/tutorial/delete/tutorial001.py
new file mode 100644 (file)
index 0000000..0f7c056
--- /dev/null
@@ -0,0 +1,100 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")
+        results = session.exec(statement)
+        hero_1 = results.one()
+        print("Hero 1:", hero_1)
+
+        statement = select(Hero).where(Hero.name == "Captain North America")
+        results = session.exec(statement)
+        hero_2 = results.one()
+        print("Hero 2:", hero_2)
+
+        hero_1.age = 16
+        hero_1.name = "Spider-Youngster"
+        session.add(hero_1)
+
+        hero_2.name = "Captain North America Except Canada"
+        hero_2.age = 110
+        session.add(hero_2)
+
+        session.commit()
+        session.refresh(hero_1)
+        session.refresh(hero_2)
+
+        print("Updated hero 1:", hero_1)
+        print("Updated hero 2:", hero_2)
+
+
+def delete_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Youngster")
+        results = session.exec(statement)
+        hero = results.one()
+        print("Hero: ", hero)
+
+        session.delete(hero)
+        session.commit()
+
+        print("Deleted hero:", hero)
+
+        statement = select(Hero).where(Hero.name == "Spider-Youngster")
+        results = session.exec(statement)
+        hero = results.first()
+
+        if hero is None:
+            print("There's no hero named Spider-Youngster")
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+    delete_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/delete/tutorial002.py b/docs_src/tutorial/delete/tutorial002.py
new file mode 100644 (file)
index 0000000..1f26711
--- /dev/null
@@ -0,0 +1,101 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")
+        results = session.exec(statement)
+        hero_1 = results.one()
+        print("Hero 1:", hero_1)
+
+        statement = select(Hero).where(Hero.name == "Captain North America")
+        results = session.exec(statement)
+        hero_2 = results.one()
+        print("Hero 2:", hero_2)
+
+        hero_1.age = 16
+        hero_1.name = "Spider-Youngster"
+        session.add(hero_1)
+
+        hero_2.name = "Captain North America Except Canada"
+        hero_2.age = 110
+        session.add(hero_2)
+
+        session.commit()
+        session.refresh(hero_1)
+        session.refresh(hero_2)
+
+        print("Updated hero 1:", hero_1)
+        print("Updated hero 2:", hero_2)
+
+
+def delete_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Youngster")  # (1)
+        results = session.exec(statement)  # (2)
+        hero = results.one()  # (3)
+        print("Hero: ", hero)  # (4)
+
+        session.delete(hero)  # (5)
+        session.commit()  # (6)
+
+        print("Deleted hero:", hero)  # (7)
+
+        statement = select(Hero).where(Hero.name == "Spider-Youngster")  # (8)
+        results = session.exec(statement)  # (9)
+        hero = results.first()  # (10)
+
+        if hero is None:  # (11)
+            print("There's no hero named Spider-Youngster")  # (12)
+    # (13)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+    delete_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/fastapi/__init__.py b/docs_src/tutorial/fastapi/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/app_testing/__init__.py b/docs_src/tutorial/fastapi/app_testing/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/__init__.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/main.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/main.py
new file mode 100644 (file)
index 0000000..02f5ab8
--- /dev/null
@@ -0,0 +1,107 @@
+from typing import List, Optional
+
+from fastapi import Depends, FastAPI, HTTPException, Query
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+class HeroUpdate(SQLModel):
+    name: Optional[str] = None
+    secret_name: Optional[str] = None
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+def get_session():
+    with Session(engine) as session:
+        yield session
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(*, session: Session = Depends(get_session), hero: HeroCreate):
+    db_hero = Hero.from_orm(hero)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(
+    *,
+    session: Session = Depends(get_session),
+    offset: int = 0,
+    limit: int = Query(default=100, lte=100),
+):
+    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+    return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(*, session: Session = Depends(get_session), hero_id: int):
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    return hero
+
+
+@app.patch("/heroes/{hero_id}", response_model=HeroRead)
+def update_hero(
+    *, session: Session = Depends(get_session), hero_id: int, hero: HeroUpdate
+):
+    db_hero = session.get(Hero, hero_id)
+    if not db_hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    hero_data = hero.dict(exclude_unset=True)
+    for key, value in hero_data.items():
+        setattr(db_hero, key, value)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.delete("/heroes/{hero_id}")
+def delete_hero(*, session: Session = Depends(get_session), hero_id: int):
+
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    session.delete(hero)
+    session.commit()
+    return {"ok": True}
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main.py
new file mode 100644 (file)
index 0000000..435787c
--- /dev/null
@@ -0,0 +1,125 @@
+import pytest
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+from sqlmodel.pool import StaticPool
+
+from .main import Hero, app, get_session
+
+
+@pytest.fixture(name="session")
+def session_fixture():
+    engine = create_engine(
+        "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
+    )
+    SQLModel.metadata.create_all(engine)
+    with Session(engine) as session:
+        yield session
+
+
+@pytest.fixture(name="client")
+def client_fixture(session: Session):
+    def get_session_override():
+        return session
+
+    app.dependency_overrides[get_session] = get_session_override
+    client = TestClient(app)
+    yield client
+    app.dependency_overrides.clear()
+
+
+def test_create_hero(client: TestClient):
+    response = client.post(
+        "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+    )
+    data = response.json()
+
+    assert response.status_code == 200
+    assert data["name"] == "Deadpond"
+    assert data["secret_name"] == "Dive Wilson"
+    assert data["age"] is None
+    assert data["id"] is not None
+
+
+def test_create_hero_incomplete(client: TestClient):
+    # No secret_name
+    response = client.post("/heroes/", json={"name": "Deadpond"})
+    assert response.status_code == 422
+
+
+def test_create_hero_invalid(client: TestClient):
+    # secret_name has an invalid type
+    response = client.post(
+        "/heroes/",
+        json={
+            "name": "Deadpond",
+            "secret_name": {"message": "Do you wanna know my secret identity?"},
+        },
+    )
+    assert response.status_code == 422
+
+
+def test_read_heroes(session: Session, client: TestClient):
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    session.add(hero_1)
+    session.add(hero_2)
+    session.commit()
+
+    response = client.get("/heroes/")
+    data = response.json()
+
+    assert response.status_code == 200
+
+    assert len(data) == 2
+    assert data[0]["name"] == hero_1.name
+    assert data[0]["secret_name"] == hero_1.secret_name
+    assert data[0]["age"] == hero_1.age
+    assert data[0]["id"] == hero_1.id
+    assert data[1]["name"] == hero_2.name
+    assert data[1]["secret_name"] == hero_2.secret_name
+    assert data[1]["age"] == hero_2.age
+    assert data[1]["id"] == hero_2.id
+
+
+def test_read_hero(session: Session, client: TestClient):
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    session.add(hero_1)
+    session.commit()
+
+    response = client.get(f"/heroes/{hero_1.id}")
+    data = response.json()
+
+    assert response.status_code == 200
+    assert data["name"] == hero_1.name
+    assert data["secret_name"] == hero_1.secret_name
+    assert data["age"] == hero_1.age
+    assert data["id"] == hero_1.id
+
+
+def test_update_hero(session: Session, client: TestClient):
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    session.add(hero_1)
+    session.commit()
+
+    response = client.patch(f"/heroes/{hero_1.id}", json={"name": "Deadpuddle"})
+    data = response.json()
+
+    assert response.status_code == 200
+    assert data["name"] == "Deadpuddle"
+    assert data["secret_name"] == "Dive Wilson"
+    assert data["age"] is None
+    assert data["id"] == hero_1.id
+
+
+def test_delete_hero(session: Session, client: TestClient):
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    session.add(hero_1)
+    session.commit()
+
+    response = client.delete(f"/heroes/{hero_1.id}")
+
+    hero_in_db = session.get(Hero, hero_1.id)
+
+    assert response.status_code == 200
+
+    assert hero_in_db is None
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_001.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_001.py
new file mode 100644 (file)
index 0000000..38ab1f1
--- /dev/null
@@ -0,0 +1,32 @@
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+
+from .main import app, get_session  # (1)
+
+
+def test_create_hero():
+    engine = create_engine(
+        "sqlite:///testing.db", connect_args={"check_same_thread": False}
+    )
+    SQLModel.metadata.create_all(engine)
+
+    with Session(engine) as session:
+
+        def get_session_override():
+            return session
+
+        app.dependency_overrides[get_session] = get_session_override
+
+        client = TestClient(app)  # (2)
+
+        response = client.post(  # (3)
+            "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+        )
+        app.dependency_overrides.clear()
+        data = response.json()  # (4)
+
+        assert response.status_code == 200  # (5)
+        assert data["name"] == "Deadpond"  # (6)
+        assert data["secret_name"] == "Dive Wilson"  # (7)
+        assert data["age"] is None  # (8)
+        assert data["id"] is not None  # (9)
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_002.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_002.py
new file mode 100644 (file)
index 0000000..144360a
--- /dev/null
@@ -0,0 +1,32 @@
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+
+from .main import app, get_session  # (1)
+
+
+def test_create_hero():
+    engine = create_engine(
+        "sqlite:///testing.db", connect_args={"check_same_thread": False}
+    )
+    SQLModel.metadata.create_all(engine)
+
+    with Session(engine) as session:
+
+        def get_session_override():  # (2)
+            return session  # (3)
+
+        app.dependency_overrides[get_session] = get_session_override  # (4)
+
+        client = TestClient(app)
+
+        response = client.post(
+            "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+        )
+        app.dependency_overrides.clear()  # (5)
+        data = response.json()
+
+        assert response.status_code == 200
+        assert data["name"] == "Deadpond"
+        assert data["secret_name"] == "Dive Wilson"
+        assert data["age"] is None
+        assert data["id"] is not None
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_003.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_003.py
new file mode 100644 (file)
index 0000000..5de06f8
--- /dev/null
@@ -0,0 +1,33 @@
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+
+from .main import app, get_session  # (1)
+
+
+def test_create_hero():
+    engine = create_engine(  # (2)
+        "sqlite:///testing.db", connect_args={"check_same_thread": False}
+    )
+    SQLModel.metadata.create_all(engine)  # (3)
+
+    with Session(engine) as session:  # (4)
+
+        def get_session_override():
+            return session  # (5)
+
+        app.dependency_overrides[get_session] = get_session_override  # (4)
+
+        client = TestClient(app)
+
+        response = client.post(
+            "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+        )
+        app.dependency_overrides.clear()
+        data = response.json()
+
+        assert response.status_code == 200
+        assert data["name"] == "Deadpond"
+        assert data["secret_name"] == "Dive Wilson"
+        assert data["age"] is None
+        assert data["id"] is not None
+    # (6)
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_004.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_004.py
new file mode 100644 (file)
index 0000000..f14fce8
--- /dev/null
@@ -0,0 +1,35 @@
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+from sqlmodel.pool import StaticPool  # (1)
+
+from .main import app, get_session
+
+
+def test_create_hero():
+    engine = create_engine(
+        "sqlite://",  # (2)
+        connect_args={"check_same_thread": False},
+        poolclass=StaticPool,  # (3)
+    )
+    SQLModel.metadata.create_all(engine)
+
+    with Session(engine) as session:
+
+        def get_session_override():
+            return session
+
+        app.dependency_overrides[get_session] = get_session_override
+
+        client = TestClient(app)
+
+        response = client.post(
+            "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+        )
+        app.dependency_overrides.clear()
+        data = response.json()
+
+        assert response.status_code == 200
+        assert data["name"] == "Deadpond"
+        assert data["secret_name"] == "Dive Wilson"
+        assert data["age"] is None
+        assert data["id"] is not None
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_005.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_005.py
new file mode 100644 (file)
index 0000000..b5200e6
--- /dev/null
@@ -0,0 +1,37 @@
+import pytest  # (1)
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+from sqlmodel.pool import StaticPool
+
+from .main import app, get_session
+
+
+@pytest.fixture(name="session")  # (2)
+def session_fixture():  # (3)
+    engine = create_engine(
+        "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
+    )
+    SQLModel.metadata.create_all(engine)
+    with Session(engine) as session:
+        yield session  # (4)
+
+
+def test_create_hero(session: Session):  # (5)
+    def get_session_override():
+        return session  # (6)
+
+    app.dependency_overrides[get_session] = get_session_override
+
+    client = TestClient(app)
+
+    response = client.post(
+        "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+    )
+    app.dependency_overrides.clear()
+    data = response.json()
+
+    assert response.status_code == 200
+    assert data["name"] == "Deadpond"
+    assert data["secret_name"] == "Dive Wilson"
+    assert data["age"] is None
+    assert data["id"] is not None
diff --git a/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_006.py b/docs_src/tutorial/fastapi/app_testing/tutorial001/test_main_006.py
new file mode 100644 (file)
index 0000000..577d56d
--- /dev/null
@@ -0,0 +1,41 @@
+import pytest
+from fastapi.testclient import TestClient
+from sqlmodel import Session, SQLModel, create_engine
+from sqlmodel.pool import StaticPool
+
+from .main import app, get_session
+
+
+@pytest.fixture(name="session")
+def session_fixture():
+    engine = create_engine(
+        "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
+    )
+    SQLModel.metadata.create_all(engine)
+    with Session(engine) as session:
+        yield session
+
+
+@pytest.fixture(name="client")  # (1)
+def client_fixture(session: Session):  # (2)
+    def get_session_override():  # (3)
+        return session
+
+    app.dependency_overrides[get_session] = get_session_override  # (4)
+
+    client = TestClient(app)  # (5)
+    yield client  # (6)
+    app.dependency_overrides.clear()  # (7)
+
+
+def test_create_hero(client: TestClient):  # (8)
+    response = client.post(
+        "/heroes/", json={"name": "Deadpond", "secret_name": "Dive Wilson"}
+    )
+    data = response.json()
+
+    assert response.status_code == 200
+    assert data["name"] == "Deadpond"
+    assert data["secret_name"] == "Dive Wilson"
+    assert data["age"] is None
+    assert data["id"] is not None
diff --git a/docs_src/tutorial/fastapi/delete/__init__.py b/docs_src/tutorial/fastapi/delete/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/delete/tutorial001.py b/docs_src/tutorial/fastapi/delete/tutorial001.py
new file mode 100644 (file)
index 0000000..19ab2bb
--- /dev/null
@@ -0,0 +1,99 @@
+from typing import List, Optional
+
+from fastapi import FastAPI, HTTPException, Query
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+class HeroUpdate(SQLModel):
+    name: Optional[str] = None
+    secret_name: Optional[str] = None
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(hero: HeroCreate):
+    with Session(engine) as session:
+        db_hero = Hero.from_orm(hero)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(offset: int = 0, limit: int = Query(default=100, lte=100)):
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+        return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(hero_id: int):
+    with Session(engine) as session:
+        hero = session.get(Hero, hero_id)
+        if not hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        return hero
+
+
+@app.patch("/heroes/{hero_id}", response_model=HeroRead)
+def update_hero(hero_id: int, hero: HeroUpdate):
+    with Session(engine) as session:
+        db_hero = session.get(Hero, hero_id)
+        if not db_hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        hero_data = hero.dict(exclude_unset=True)
+        for key, value in hero_data.items():
+            setattr(db_hero, key, value)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.delete("/heroes/{hero_id}")
+def delete_hero(hero_id: int):
+    with Session(engine) as session:
+        hero = session.get(Hero, hero_id)
+        if not hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        session.delete(hero)
+        session.commit()
+        return {"ok": True}
diff --git a/docs_src/tutorial/fastapi/limit_and_offset/__init__.py b/docs_src/tutorial/fastapi/limit_and_offset/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/limit_and_offset/tutorial001.py b/docs_src/tutorial/fastapi/limit_and_offset/tutorial001.py
new file mode 100644 (file)
index 0000000..9bdf604
--- /dev/null
@@ -0,0 +1,67 @@
+from typing import List, Optional
+
+from fastapi import FastAPI, HTTPException, Query
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(hero: HeroCreate):
+    with Session(engine) as session:
+        db_hero = Hero.from_orm(hero)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(offset: int = 0, limit: int = Query(default=100, lte=100)):
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+        return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(hero_id: int):
+    with Session(engine) as session:
+        hero = session.get(Hero, hero_id)
+        if not hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        return hero
diff --git a/docs_src/tutorial/fastapi/multiple_models/__init__.py b/docs_src/tutorial/fastapi/multiple_models/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/multiple_models/tutorial001.py b/docs_src/tutorial/fastapi/multiple_models/tutorial001.py
new file mode 100644 (file)
index 0000000..c46448b
--- /dev/null
@@ -0,0 +1,60 @@
+from typing import List, Optional
+
+from fastapi import FastAPI
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class HeroCreate(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class HeroRead(SQLModel):
+    id: int
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(hero: HeroCreate):
+    with Session(engine) as session:
+        db_hero = Hero.from_orm(hero)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes():
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero)).all()
+        return heroes
diff --git a/docs_src/tutorial/fastapi/multiple_models/tutorial002.py b/docs_src/tutorial/fastapi/multiple_models/tutorial002.py
new file mode 100644 (file)
index 0000000..537e896
--- /dev/null
@@ -0,0 +1,58 @@
+from typing import List, Optional
+
+from fastapi import FastAPI
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(hero: HeroCreate):
+    with Session(engine) as session:
+        db_hero = Hero.from_orm(hero)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes():
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero)).all()
+        return heroes
diff --git a/docs_src/tutorial/fastapi/read_one/__init__.py b/docs_src/tutorial/fastapi/read_one/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/read_one/tutorial001.py b/docs_src/tutorial/fastapi/read_one/tutorial001.py
new file mode 100644 (file)
index 0000000..bc83db5
--- /dev/null
@@ -0,0 +1,67 @@
+from typing import List, Optional
+
+from fastapi import FastAPI, HTTPException
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(hero: HeroCreate):
+    with Session(engine) as session:
+        db_hero = Hero.from_orm(hero)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes():
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero)).all()
+        return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(hero_id: int):
+    with Session(engine) as session:
+        hero = session.get(Hero, hero_id)
+        if not hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        return hero
diff --git a/docs_src/tutorial/fastapi/relationships/__init__.py b/docs_src/tutorial/fastapi/relationships/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/relationships/tutorial001.py b/docs_src/tutorial/fastapi/relationships/tutorial001.py
new file mode 100644 (file)
index 0000000..da21e46
--- /dev/null
@@ -0,0 +1,202 @@
+from typing import List, Optional
+
+from fastapi import Depends, FastAPI, HTTPException, Query
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
+
+
+class TeamBase(SQLModel):
+    name: str
+    headquarters: str
+
+
+class Team(TeamBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class TeamCreate(TeamBase):
+    pass
+
+
+class TeamRead(TeamBase):
+    id: int
+
+
+class TeamUpdate(SQLModel):
+    id: Optional[int] = None
+    name: Optional[str] = None
+    headquarters: Optional[str] = None
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+    team: Optional[Team] = Relationship(back_populates="heroes")
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroUpdate(SQLModel):
+    name: Optional[str] = None
+    secret_name: Optional[str] = None
+    age: Optional[int] = None
+    team_id: Optional[int] = None
+
+
+class HeroReadWithTeam(HeroRead):
+    team: Optional[TeamRead] = None
+
+
+class TeamReadWithHeroes(TeamRead):
+    heroes: List[HeroRead] = []
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+def get_session():
+    with Session(engine) as session:
+        yield session
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(*, session: Session = Depends(get_session), hero: HeroCreate):
+    db_hero = Hero.from_orm(hero)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(
+    *,
+    session: Session = Depends(get_session),
+    offset: int = 0,
+    limit: int = Query(default=100, lte=100),
+):
+    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+    return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroReadWithTeam)
+def read_hero(*, session: Session = Depends(get_session), hero_id: int):
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    return hero
+
+
+@app.patch("/heroes/{hero_id}", response_model=HeroRead)
+def update_hero(
+    *, session: Session = Depends(get_session), hero_id: int, hero: HeroUpdate
+):
+    db_hero = session.get(Hero, hero_id)
+    if not db_hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    hero_data = hero.dict(exclude_unset=True)
+    for key, value in hero_data.items():
+        setattr(db_hero, key, value)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.delete("/heroes/{hero_id}")
+def delete_hero(*, session: Session = Depends(get_session), hero_id: int):
+
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    session.delete(hero)
+    session.commit()
+    return {"ok": True}
+
+
+@app.post("/teams/", response_model=TeamRead)
+def create_team(*, session: Session = Depends(get_session), team: TeamCreate):
+    db_team = Team.from_orm(team)
+    session.add(db_team)
+    session.commit()
+    session.refresh(db_team)
+    return db_team
+
+
+@app.get("/teams/", response_model=List[TeamRead])
+def read_teams(
+    *,
+    session: Session = Depends(get_session),
+    offset: int = 0,
+    limit: int = Query(default=100, lte=100),
+):
+    teams = session.exec(select(Team).offset(offset).limit(limit)).all()
+    return teams
+
+
+@app.get("/teams/{team_id}", response_model=TeamReadWithHeroes)
+def read_team(*, team_id: int, session: Session = Depends(get_session)):
+    team = session.get(Team, team_id)
+    if not team:
+        raise HTTPException(status_code=404, detail="Team not found")
+    return team
+
+
+@app.patch("/teams/{team_id}", response_model=TeamRead)
+def update_team(
+    *,
+    session: Session = Depends(get_session),
+    team_id: int,
+    team: TeamUpdate,
+):
+    db_team = session.get(Team, team_id)
+    if not db_team:
+        raise HTTPException(status_code=404, detail="Team not found")
+    team_data = team.dict(exclude_unset=True)
+    for key, value in team_data.items():
+        setattr(db_team, key, value)
+    session.add(db_team)
+    session.commit()
+    session.refresh(db_team)
+    return db_team
+
+
+@app.delete("/teams/{team_id}")
+def delete_team(*, session: Session = Depends(get_session), team_id: int):
+    team = session.get(Team, team_id)
+    if not team:
+        raise HTTPException(status_code=404, detail="Team not found")
+    session.delete(team)
+    session.commit()
+    return {"ok": True}
diff --git a/docs_src/tutorial/fastapi/response_model/__init__.py b/docs_src/tutorial/fastapi/response_model/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/response_model/tutorial001.py b/docs_src/tutorial/fastapi/response_model/tutorial001.py
new file mode 100644 (file)
index 0000000..5f7a190
--- /dev/null
@@ -0,0 +1,46 @@
+from typing import List, Optional
+
+from fastapi import FastAPI
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=Hero)
+def create_hero(hero: Hero):
+    with Session(engine) as session:
+        session.add(hero)
+        session.commit()
+        session.refresh(hero)
+        return hero
+
+
+@app.get("/heroes/", response_model=List[Hero])
+def read_heroes():
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero)).all()
+        return heroes
diff --git a/docs_src/tutorial/fastapi/session_with_dependency/__init__.py b/docs_src/tutorial/fastapi/session_with_dependency/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py b/docs_src/tutorial/fastapi/session_with_dependency/tutorial001.py
new file mode 100644 (file)
index 0000000..02f5ab8
--- /dev/null
@@ -0,0 +1,107 @@
+from typing import List, Optional
+
+from fastapi import Depends, FastAPI, HTTPException, Query
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+class HeroUpdate(SQLModel):
+    name: Optional[str] = None
+    secret_name: Optional[str] = None
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+def get_session():
+    with Session(engine) as session:
+        yield session
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(*, session: Session = Depends(get_session), hero: HeroCreate):
+    db_hero = Hero.from_orm(hero)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(
+    *,
+    session: Session = Depends(get_session),
+    offset: int = 0,
+    limit: int = Query(default=100, lte=100),
+):
+    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+    return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(*, session: Session = Depends(get_session), hero_id: int):
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    return hero
+
+
+@app.patch("/heroes/{hero_id}", response_model=HeroRead)
+def update_hero(
+    *, session: Session = Depends(get_session), hero_id: int, hero: HeroUpdate
+):
+    db_hero = session.get(Hero, hero_id)
+    if not db_hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    hero_data = hero.dict(exclude_unset=True)
+    for key, value in hero_data.items():
+        setattr(db_hero, key, value)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.delete("/heroes/{hero_id}")
+def delete_hero(*, session: Session = Depends(get_session), hero_id: int):
+
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    session.delete(hero)
+    session.commit()
+    return {"ok": True}
diff --git a/docs_src/tutorial/fastapi/simple_hero_api/__init__.py b/docs_src/tutorial/fastapi/simple_hero_api/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py b/docs_src/tutorial/fastapi/simple_hero_api/tutorial001.py
new file mode 100644 (file)
index 0000000..715836c
--- /dev/null
@@ -0,0 +1,46 @@
+from typing import Optional
+
+from fastapi import FastAPI
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/")
+def create_hero(hero: Hero):
+    with Session(engine) as session:
+        session.add(hero)
+        session.commit()
+        session.refresh(hero)
+        return hero
+
+
+@app.get("/heroes/")
+def read_heroes():
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero)).all()
+        return heroes
diff --git a/docs_src/tutorial/fastapi/teams/__init__.py b/docs_src/tutorial/fastapi/teams/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/teams/tutorial001.py b/docs_src/tutorial/fastapi/teams/tutorial001.py
new file mode 100644 (file)
index 0000000..dc3e093
--- /dev/null
@@ -0,0 +1,194 @@
+from typing import List, Optional
+
+from fastapi import Depends, FastAPI, HTTPException, Query
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
+
+
+class TeamBase(SQLModel):
+    name: str
+    headquarters: str
+
+
+class Team(TeamBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class TeamCreate(TeamBase):
+    pass
+
+
+class TeamRead(TeamBase):
+    id: int
+
+
+class TeamUpdate(SQLModel):
+    id: Optional[int] = None
+    name: Optional[str] = None
+    headquarters: Optional[str] = None
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+    team: Optional[Team] = Relationship(back_populates="heroes")
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroUpdate(SQLModel):
+    name: Optional[str] = None
+    secret_name: Optional[str] = None
+    age: Optional[int] = None
+    team_id: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+def get_session():
+    with Session(engine) as session:
+        yield session
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(*, session: Session = Depends(get_session), hero: HeroCreate):
+    db_hero = Hero.from_orm(hero)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(
+    *,
+    session: Session = Depends(get_session),
+    offset: int = 0,
+    limit: int = Query(default=100, lte=100),
+):
+    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+    return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(*, session: Session = Depends(get_session), hero_id: int):
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    return hero
+
+
+@app.patch("/heroes/{hero_id}", response_model=HeroRead)
+def update_hero(
+    *, session: Session = Depends(get_session), hero_id: int, hero: HeroUpdate
+):
+    db_hero = session.get(Hero, hero_id)
+    if not db_hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    hero_data = hero.dict(exclude_unset=True)
+    for key, value in hero_data.items():
+        setattr(db_hero, key, value)
+    session.add(db_hero)
+    session.commit()
+    session.refresh(db_hero)
+    return db_hero
+
+
+@app.delete("/heroes/{hero_id}")
+def delete_hero(*, session: Session = Depends(get_session), hero_id: int):
+
+    hero = session.get(Hero, hero_id)
+    if not hero:
+        raise HTTPException(status_code=404, detail="Hero not found")
+    session.delete(hero)
+    session.commit()
+    return {"ok": True}
+
+
+@app.post("/teams/", response_model=TeamRead)
+def create_team(*, session: Session = Depends(get_session), team: TeamCreate):
+    db_team = Team.from_orm(team)
+    session.add(db_team)
+    session.commit()
+    session.refresh(db_team)
+    return db_team
+
+
+@app.get("/teams/", response_model=List[TeamRead])
+def read_teams(
+    *,
+    session: Session = Depends(get_session),
+    offset: int = 0,
+    limit: int = Query(default=100, lte=100),
+):
+    teams = session.exec(select(Team).offset(offset).limit(limit)).all()
+    return teams
+
+
+@app.get("/teams/{team_id}", response_model=TeamRead)
+def read_team(*, team_id: int, session: Session = Depends(get_session)):
+    team = session.get(Team, team_id)
+    if not team:
+        raise HTTPException(status_code=404, detail="Team not found")
+    return team
+
+
+@app.patch("/teams/{team_id}", response_model=TeamRead)
+def update_team(
+    *,
+    session: Session = Depends(get_session),
+    team_id: int,
+    team: TeamUpdate,
+):
+    db_team = session.get(Team, team_id)
+    if not db_team:
+        raise HTTPException(status_code=404, detail="Team not found")
+    team_data = team.dict(exclude_unset=True)
+    for key, value in team_data.items():
+        setattr(db_team, key, value)
+    session.add(db_team)
+    session.commit()
+    session.refresh(db_team)
+    return db_team
+
+
+@app.delete("/teams/{team_id}")
+def delete_team(*, session: Session = Depends(get_session), team_id: int):
+    team = session.get(Team, team_id)
+    if not team:
+        raise HTTPException(status_code=404, detail="Team not found")
+    session.delete(team)
+    session.commit()
+    return {"ok": True}
diff --git a/docs_src/tutorial/fastapi/update/__init__.py b/docs_src/tutorial/fastapi/update/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/fastapi/update/tutorial001.py b/docs_src/tutorial/fastapi/update/tutorial001.py
new file mode 100644 (file)
index 0000000..9309d62
--- /dev/null
@@ -0,0 +1,88 @@
+from typing import List, Optional
+
+from fastapi import FastAPI, HTTPException, Query
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class HeroBase(SQLModel):
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+class Hero(HeroBase, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+
+
+class HeroCreate(HeroBase):
+    pass
+
+
+class HeroRead(HeroBase):
+    id: int
+
+
+class HeroUpdate(SQLModel):
+    name: Optional[str] = None
+    secret_name: Optional[str] = None
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+connect_args = {"check_same_thread": False}
+engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)
+
+
+app = FastAPI()
+
+
+@app.on_event("startup")
+def on_startup():
+    create_db_and_tables()
+
+
+@app.post("/heroes/", response_model=HeroRead)
+def create_hero(hero: HeroCreate):
+    with Session(engine) as session:
+        db_hero = Hero.from_orm(hero)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
+
+
+@app.get("/heroes/", response_model=List[HeroRead])
+def read_heroes(offset: int = 0, limit: int = Query(default=100, lte=100)):
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
+        return heroes
+
+
+@app.get("/heroes/{hero_id}", response_model=HeroRead)
+def read_hero(hero_id: int):
+    with Session(engine) as session:
+        hero = session.get(Hero, hero_id)
+        if not hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        return hero
+
+
+@app.patch("/heroes/{hero_id}", response_model=HeroRead)
+def update_hero(hero_id: int, hero: HeroUpdate):
+    with Session(engine) as session:
+        db_hero = session.get(Hero, hero_id)
+        if not db_hero:
+            raise HTTPException(status_code=404, detail="Hero not found")
+        hero_data = hero.dict(exclude_unset=True)
+        for key, value in hero_data.items():
+            setattr(db_hero, key, value)
+        session.add(db_hero)
+        session.commit()
+        session.refresh(db_hero)
+        return db_hero
diff --git a/docs_src/tutorial/insert/__init__.py b/docs_src/tutorial/insert/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/insert/tutorial001.py b/docs_src/tutorial/insert/tutorial001.py
new file mode 100644 (file)
index 0000000..17050e9
--- /dev/null
@@ -0,0 +1,45 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    session = Session(engine)
+
+    session.add(hero_1)
+    session.add(hero_2)
+    session.add(hero_3)
+
+    session.commit()
+
+    session.close()
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/insert/tutorial002.py b/docs_src/tutorial/insert/tutorial002.py
new file mode 100644 (file)
index 0000000..3ff10c8
--- /dev/null
@@ -0,0 +1,42 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/insert/tutorial003.py b/docs_src/tutorial/insert/tutorial003.py
new file mode 100644 (file)
index 0000000..8133f29
--- /dev/null
@@ -0,0 +1,43 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():  # (1)
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")  # (2)
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:  # (3)
+        session.add(hero_1)  # (4)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()  # (5)
+    # (6)
+
+
+def main():  # (7)
+    create_db_and_tables()  # (8)
+    create_heroes()  # (9)
+
+
+if __name__ == "__main__":  # (10)
+    main()  # (11)
diff --git a/docs_src/tutorial/many_to_many/__init__.py b/docs_src/tutorial/many_to_many/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/many_to_many/tutorial001.py b/docs_src/tutorial/many_to_many/tutorial001.py
new file mode 100644 (file)
index 0000000..aee77af
--- /dev/null
@@ -0,0 +1,84 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine
+
+
+class HeroTeamLink(SQLModel, table=True):
+    team_id: Optional[int] = Field(
+        default=None, foreign_key="team.id", primary_key=True
+    )
+    hero_id: Optional[int] = Field(
+        default=None, foreign_key="hero.id", primary_key=True
+    )
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="teams", link_model=HeroTeamLink)
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    teams: List[Team] = Relationship(back_populates="heroes", link_model=HeroTeamLink)
+
+
+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",
+            teams=[team_z_force, team_preventers],
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            teams=[team_preventers],
+        )
+        hero_spider_boy = Hero(
+            name="Spider-Boy", secret_name="Pedro Parqueador", teams=[team_preventers]
+        )
+        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("Deadpond:", hero_deadpond)
+        print("Deadpond teams:", hero_deadpond.teams)
+        print("Rusty-Man:", hero_rusty_man)
+        print("Rusty-Man Teams:", hero_rusty_man.teams)
+        print("Spider-Boy:", hero_spider_boy)
+        print("Spider-Boy Teams:", hero_spider_boy.teams)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/many_to_many/tutorial002.py b/docs_src/tutorial/many_to_many/tutorial002.py
new file mode 100644 (file)
index 0000000..123fa5a
--- /dev/null
@@ -0,0 +1,107 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
+
+
+class HeroTeamLink(SQLModel, table=True):
+    team_id: Optional[int] = Field(
+        default=None, foreign_key="team.id", primary_key=True
+    )
+    hero_id: Optional[int] = Field(
+        default=None, foreign_key="hero.id", primary_key=True
+    )
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="teams", link_model=HeroTeamLink)
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    teams: List[Team] = Relationship(back_populates="heroes", link_model=HeroTeamLink)
+
+
+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",
+            teams=[team_z_force, team_preventers],
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+            teams=[team_preventers],
+        )
+        hero_spider_boy = Hero(
+            name="Spider-Boy", secret_name="Pedro Parqueador", teams=[team_preventers]
+        )
+        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("Deadpond:", hero_deadpond)
+        print("Deadpond teams:", hero_deadpond.teams)
+        print("Rusty-Man:", hero_rusty_man)
+        print("Rusty-Man Teams:", hero_rusty_man.teams)
+        print("Spider-Boy:", hero_spider_boy)
+        print("Spider-Boy Teams:", hero_spider_boy.teams)
+
+
+def update_heroes():
+    with Session(engine) as session:
+        hero_spider_boy = session.exec(
+            select(Hero).where(Hero.name == "Spider-Boy")
+        ).one()
+        team_z_force = session.exec(select(Team).where(Team.name == "Z-Force")).one()
+
+        team_z_force.heroes.append(hero_spider_boy)
+        session.add(team_z_force)
+        session.commit()
+
+        print("Updated Spider-Boy's Teams:", hero_spider_boy.teams)
+        print("Z-Force heroes:", team_z_force.heroes)
+
+        hero_spider_boy.teams.remove(team_z_force)
+        session.add(team_z_force)
+        session.commit()
+
+        print("Reverted Z-Force's heroes:", team_z_force.heroes)
+        print("Reverted Spider-Boy's teams:", hero_spider_boy.teams)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/many_to_many/tutorial003.py b/docs_src/tutorial/many_to_many/tutorial003.py
new file mode 100644 (file)
index 0000000..c2f3d56
--- /dev/null
@@ -0,0 +1,123 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select
+
+
+class HeroTeamLink(SQLModel, table=True):
+    team_id: Optional[int] = Field(
+        default=None, foreign_key="team.id", primary_key=True
+    )
+    hero_id: Optional[int] = Field(
+        default=None, foreign_key="hero.id", primary_key=True
+    )
+    is_training: bool = False
+
+    team: "Team" = Relationship(back_populates="hero_links")
+    hero: "Hero" = Relationship(back_populates="team_links")
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    hero_links: List[HeroTeamLink] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_links: List[HeroTeamLink] = Relationship(back_populates="hero")
+
+
+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",
+        )
+        hero_rusty_man = Hero(
+            name="Rusty-Man",
+            secret_name="Tommy Sharp",
+            age=48,
+        )
+        hero_spider_boy = Hero(
+            name="Spider-Boy",
+            secret_name="Pedro Parqueador",
+        )
+        deadpond_team_z_link = HeroTeamLink(team=team_z_force, hero=hero_deadpond)
+        deadpond_preventers_link = HeroTeamLink(
+            team=team_preventers, hero=hero_deadpond, is_training=True
+        )
+        spider_boy_preventers_link = HeroTeamLink(
+            team=team_preventers, hero=hero_spider_boy, is_training=True
+        )
+        rusty_man_preventers_link = HeroTeamLink(
+            team=team_preventers, hero=hero_rusty_man
+        )
+
+        session.add(deadpond_team_z_link)
+        session.add(deadpond_preventers_link)
+        session.add(spider_boy_preventers_link)
+        session.add(rusty_man_preventers_link)
+        session.commit()
+
+        for link in team_z_force.hero_links:
+            print("Z-Force hero:", link.hero, "is training:", link.is_training)
+
+        for link in team_preventers.hero_links:
+            print("Preventers hero:", link.hero, "is training:", link.is_training)
+
+
+def update_heroes():
+    with Session(engine) as session:
+        hero_spider_boy = session.exec(
+            select(Hero).where(Hero.name == "Spider-Boy")
+        ).one()
+        team_z_force = session.exec(select(Team).where(Team.name == "Z-Force")).one()
+
+        spider_boy_z_force_link = HeroTeamLink(
+            team=team_z_force, hero=hero_spider_boy, is_training=True
+        )
+        team_z_force.hero_links.append(spider_boy_z_force_link)
+        session.add(team_z_force)
+        session.commit()
+
+        print("Updated Spider-Boy's Teams:", hero_spider_boy.team_links)
+        print("Z-Force heroes:", team_z_force.hero_links)
+
+        for link in hero_spider_boy.team_links:
+            if link.team.name == "Preventers":
+                link.is_training = False
+
+        session.add(hero_spider_boy)
+        session.commit()
+
+        for link in hero_spider_boy.team_links:
+            print("Spider-Boy team:", link.team, "is training:", link.is_training)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/offset_and_limit/__init__.py b/docs_src/tutorial/offset_and_limit/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/offset_and_limit/tutorial001.py b/docs_src/tutorial/offset_and_limit/tutorial001.py
new file mode 100644 (file)
index 0000000..5413c17
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).limit(3)
+        results = session.exec(statement)
+        heroes = results.all()
+        print(heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/offset_and_limit/tutorial002.py b/docs_src/tutorial/offset_and_limit/tutorial002.py
new file mode 100644 (file)
index 0000000..9d85a13
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).offset(3).limit(3)
+        results = session.exec(statement)
+        heroes = results.all()
+        print(heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/offset_and_limit/tutorial003.py b/docs_src/tutorial/offset_and_limit/tutorial003.py
new file mode 100644 (file)
index 0000000..5d2c3bf
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).offset(6).limit(3)
+        results = session.exec(statement)
+        heroes = results.all()
+        print(heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/offset_and_limit/tutorial004.py b/docs_src/tutorial/offset_and_limit/tutorial004.py
new file mode 100644 (file)
index 0000000..bfa882d
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age > 32).limit(3)
+        results = session.exec(statement)
+        heroes = results.all()
+        print(heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/__init__.py b/docs_src/tutorial/one/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/one/tutorial001.py b/docs_src/tutorial/one/tutorial001.py
new file mode 100644 (file)
index 0000000..9fa5f0b
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age <= 35)
+        results = session.exec(statement)
+        hero = results.first()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial002.py b/docs_src/tutorial/one/tutorial002.py
new file mode 100644 (file)
index 0000000..a1d86e0
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age < 25)
+        results = session.exec(statement)
+        hero = results.first()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial003.py b/docs_src/tutorial/one/tutorial003.py
new file mode 100644 (file)
index 0000000..fe8c05c
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Deadpond")
+        results = session.exec(statement)
+        hero = results.one()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial004.py b/docs_src/tutorial/one/tutorial004.py
new file mode 100644 (file)
index 0000000..32bc9b9
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age <= 35)
+        results = session.exec(statement)
+        hero = results.one()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial005.py b/docs_src/tutorial/one/tutorial005.py
new file mode 100644 (file)
index 0000000..2382136
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age < 25)
+        results = session.exec(statement)
+        hero = results.one()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial006.py b/docs_src/tutorial/one/tutorial006.py
new file mode 100644 (file)
index 0000000..cf408c4
--- /dev/null
@@ -0,0 +1,57 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        hero = session.exec(select(Hero).where(Hero.name == "Deadpond")).one()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial007.py b/docs_src/tutorial/one/tutorial007.py
new file mode 100644 (file)
index 0000000..8a36d97
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.id == 1)
+        results = session.exec(statement)
+        hero = results.first()
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial008.py b/docs_src/tutorial/one/tutorial008.py
new file mode 100644 (file)
index 0000000..1b0d6ef
--- /dev/null
@@ -0,0 +1,57 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        hero = session.get(Hero, 1)
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/one/tutorial009.py b/docs_src/tutorial/one/tutorial009.py
new file mode 100644 (file)
index 0000000..70deed2
--- /dev/null
@@ -0,0 +1,57 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        hero = session.get(Hero, 9001)
+        print("Hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/__init__.py b/docs_src/tutorial/relationship_attributes/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/relationship_attributes/back_populates/__init__.py b/docs_src/tutorial/relationship_attributes/back_populates/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py b/docs_src/tutorial/relationship_attributes/back_populates/tutorial001.py
new file mode 100644 (file)
index 0000000..d9851b4
--- /dev/null
@@ -0,0 +1,143 @@
+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
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship()
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    team: Optional[Team] = Relationship()
+
+
+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)
+
+        hero_tarantula = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+        hero_dr_weird = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+        hero_cap = Hero(
+            name="Captain North America", secret_name="Esteban Rogelios", age=93
+        )
+
+        team_preventers.heroes.append(hero_tarantula)
+        team_preventers.heroes.append(hero_dr_weird)
+        team_preventers.heroes.append(hero_cap)
+        session.add(team_preventers)
+        session.commit()
+        session.refresh(hero_tarantula)
+        session.refresh(hero_dr_weird)
+        session.refresh(hero_cap)
+        print("Preventers new hero:", hero_tarantula)
+        print("Preventers new hero:", hero_dr_weird)
+        print("Preventers new hero:", hero_cap)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Team).where(Team.name == "Preventers")
+        result = session.exec(statement)
+        team_preventers = result.one()
+
+        print("Preventers heroes:", team_preventers.heroes)
+
+
+def update_heroes():
+    with Session(engine) as session:
+        hero_spider_boy = session.exec(
+            select(Hero).where(Hero.name == "Spider-Boy")
+        ).one()
+
+        preventers_team = session.exec(
+            select(Team).where(Team.name == "Preventers")
+        ).one()
+
+        print("Hero Spider-Boy:", hero_spider_boy)
+        print("Preventers Team:", preventers_team)
+        print("Preventers Team Heroes:", preventers_team.heroes)
+
+        hero_spider_boy.team = None
+
+        print("Spider-Boy without team:", hero_spider_boy)
+
+        print("Preventers Team Heroes again:", preventers_team.heroes)
+
+        session.add(hero_spider_boy)
+        session.commit()
+        print("After committing")
+
+        session.refresh(hero_spider_boy)
+        print("Spider-Boy after commit:", hero_spider_boy)
+
+        print("Preventers Team Heroes after commit:", preventers_team.heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py b/docs_src/tutorial/relationship_attributes/back_populates/tutorial002.py
new file mode 100644 (file)
index 0000000..b33fabe
--- /dev/null
@@ -0,0 +1,143 @@
+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
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    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)
+
+        hero_tarantula = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+        hero_dr_weird = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+        hero_cap = Hero(
+            name="Captain North America", secret_name="Esteban Rogelios", age=93
+        )
+
+        team_preventers.heroes.append(hero_tarantula)
+        team_preventers.heroes.append(hero_dr_weird)
+        team_preventers.heroes.append(hero_cap)
+        session.add(team_preventers)
+        session.commit()
+        session.refresh(hero_tarantula)
+        session.refresh(hero_dr_weird)
+        session.refresh(hero_cap)
+        print("Preventers new hero:", hero_tarantula)
+        print("Preventers new hero:", hero_dr_weird)
+        print("Preventers new hero:", hero_cap)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Team).where(Team.name == "Preventers")
+        result = session.exec(statement)
+        team_preventers = result.one()
+
+        print("Preventers heroes:", team_preventers.heroes)
+
+
+def update_heroes():
+    with Session(engine) as session:
+        hero_spider_boy = session.exec(
+            select(Hero).where(Hero.name == "Spider-Boy")
+        ).one()
+
+        preventers_team = session.exec(
+            select(Team).where(Team.name == "Preventers")
+        ).one()
+
+        print("Hero Spider-Boy:", hero_spider_boy)
+        print("Preventers Team:", preventers_team)
+        print("Preventers Team Heroes:", preventers_team.heroes)
+
+        hero_spider_boy.team = None
+
+        print("Spider-Boy without team:", hero_spider_boy)
+
+        print("Preventers Team Heroes again:", preventers_team.heroes)
+
+        session.add(hero_spider_boy)
+        session.commit()
+        print("After committing")
+
+        session.refresh(hero_spider_boy)
+        print("Spider-Boy after commit:", hero_spider_boy)
+
+        print("Preventers Team Heroes after commit:", preventers_team.heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/back_populates/tutorial003.py b/docs_src/tutorial/relationship_attributes/back_populates/tutorial003.py
new file mode 100644 (file)
index 0000000..cbd1581
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, SQLModel, create_engine
+
+
+class Weapon(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+
+    hero: "Hero" = Relationship(back_populates="weapon")
+
+
+class Power(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+
+    hero_id: int = Field(foreign_key="hero.id")
+    hero: "Hero" = Relationship(back_populates="powers")
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    team: Optional[Team] = Relationship(back_populates="heroes")
+
+    weapon_id: Optional[int] = Field(default=None, foreign_key="weapon.id")
+    weapon: Optional[Weapon] = Relationship(back_populates="owner")
+
+    powers: List[Power] = Relationship(back_populates="hero")
+
+
+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 main():
+    create_db_and_tables()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/create_and_update_relationships/__init__.py b/docs_src/tutorial/relationship_attributes/create_and_update_relationships/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/relationship_attributes/create_and_update_relationships/tutorial001.py b/docs_src/tutorial/relationship_attributes/create_and_update_relationships/tutorial001.py
new file mode 100644 (file)
index 0000000..2bf2041
--- /dev/null
@@ -0,0 +1,102 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    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)
+
+        hero_tarantula = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+        hero_dr_weird = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+        hero_cap = Hero(
+            name="Captain North America", secret_name="Esteban Rogelios", age=93
+        )
+
+        team_preventers.heroes.append(hero_tarantula)
+        team_preventers.heroes.append(hero_dr_weird)
+        team_preventers.heroes.append(hero_cap)
+        session.add(team_preventers)
+        session.commit()
+        session.refresh(hero_tarantula)
+        session.refresh(hero_dr_weird)
+        session.refresh(hero_cap)
+        print("Preventers new hero:", hero_tarantula)
+        print("Preventers new hero:", hero_dr_weird)
+        print("Preventers new hero:", hero_cap)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/define_relationship_attributes/__init__.py b/docs_src/tutorial/relationship_attributes/define_relationship_attributes/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py b/docs_src/tutorial/relationship_attributes/define_relationship_attributes/tutorial001.py
new file mode 100644 (file)
index 0000000..98c1919
--- /dev/null
@@ -0,0 +1,70 @@
+from typing import List, Optional
+
+from sqlmodel import Field, Relationship, Session, SQLModel, create_engine
+
+
+class Team(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    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()
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/read_relationships/__init__.py b/docs_src/tutorial/relationship_attributes/read_relationships/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/relationship_attributes/read_relationships/tutorial001.py b/docs_src/tutorial/relationship_attributes/read_relationships/tutorial001.py
new file mode 100644 (file)
index 0000000..e5c23a7
--- /dev/null
@@ -0,0 +1,117 @@
+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
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    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)
+
+        hero_tarantula = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+        hero_dr_weird = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+        hero_cap = Hero(
+            name="Captain North America", secret_name="Esteban Rogelios", age=93
+        )
+
+        team_preventers.heroes.append(hero_tarantula)
+        team_preventers.heroes.append(hero_dr_weird)
+        team_preventers.heroes.append(hero_cap)
+        session.add(team_preventers)
+        session.commit()
+        session.refresh(hero_tarantula)
+        session.refresh(hero_dr_weird)
+        session.refresh(hero_cap)
+        print("Preventers new hero:", hero_tarantula)
+        print("Preventers new hero:", hero_dr_weird)
+        print("Preventers new hero:", hero_cap)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")
+        result = session.exec(statement)
+        hero_spider_boy = result.one()
+
+        statement = select(Team).where(Team.id == hero_spider_boy.id)
+        result = session.exec(statement)
+        team = result.first()
+        print("Spider-Boy's team:", team)
+
+        print("Spider-Boy's team again:", hero_spider_boy.team)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/relationship_attributes/read_relationships/tutorial002.py b/docs_src/tutorial/relationship_attributes/read_relationships/tutorial002.py
new file mode 100644 (file)
index 0000000..efae8e5
--- /dev/null
@@ -0,0 +1,127 @@
+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
+    headquarters: str
+
+    heroes: List["Hero"] = Relationship(back_populates="team")
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+    team_id: Optional[int] = Field(default=None, foreign_key="team.id")
+    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)
+
+        hero_tarantula = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+        hero_dr_weird = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+        hero_cap = Hero(
+            name="Captain North America", secret_name="Esteban Rogelios", age=93
+        )
+
+        team_preventers.heroes.append(hero_tarantula)
+        team_preventers.heroes.append(hero_dr_weird)
+        team_preventers.heroes.append(hero_cap)
+        session.add(team_preventers)
+        session.commit()
+        session.refresh(hero_tarantula)
+        session.refresh(hero_dr_weird)
+        session.refresh(hero_cap)
+        print("Preventers new hero:", hero_tarantula)
+        print("Preventers new hero:", hero_dr_weird)
+        print("Preventers new hero:", hero_cap)
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Team).where(Team.name == "Preventers")
+        result = session.exec(statement)
+        team_preventers = result.one()
+
+        print("Preventers heroes:", team_preventers.heroes)
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")
+        result = session.exec(statement)
+        hero_spider_boy = result.one()
+
+        hero_spider_boy.team = None
+        session.add(hero_spider_boy)
+        session.commit()
+
+        session.refresh(hero_spider_boy)
+        print("Spider-Boy without team:", hero_spider_boy)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/select/__init__.py b/docs_src/tutorial/select/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/select/tutorial001.py b/docs_src/tutorial/select/tutorial001.py
new file mode 100644 (file)
index 0000000..285f711
--- /dev/null
@@ -0,0 +1,51 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/select/tutorial002.py b/docs_src/tutorial/select/tutorial002.py
new file mode 100644 (file)
index 0000000..4f6d102
--- /dev/null
@@ -0,0 +1,52 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select  # (1)
+
+
+class Hero(SQLModel, table=True):  # (2)
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+sqlite_file_name = "database.db"
+sqlite_url = f"sqlite:///{sqlite_file_name}"
+
+engine = create_engine(sqlite_url, echo=True)  # (3)
+
+
+def create_db_and_tables():
+    SQLModel.metadata.create_all(engine)  # (4)
+
+
+def create_heroes():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")  # (5)
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:  # (6)
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:  # (7)
+        statement = select(Hero)  # (8)
+        results = session.exec(statement)  # (9)
+        for hero in results:  # (10)
+            print(hero)  # (11)
+    # (12)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()  # (13)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/select/tutorial003.py b/docs_src/tutorial/select/tutorial003.py
new file mode 100644 (file)
index 0000000..97eab13
--- /dev/null
@@ -0,0 +1,51 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero)
+        results = session.exec(statement)
+        heroes = results.all()
+        print(heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/select/tutorial004.py b/docs_src/tutorial/select/tutorial004.py
new file mode 100644 (file)
index 0000000..e9ddbbb
--- /dev/null
@@ -0,0 +1,49 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        heroes = session.exec(select(Hero)).all()
+        print(heroes)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/update/__init__.py b/docs_src/tutorial/update/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/update/tutorial001.py b/docs_src/tutorial/update/tutorial001.py
new file mode 100644 (file)
index 0000000..96c7208
--- /dev/null
@@ -0,0 +1,65 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")
+        results = session.exec(statement)
+        hero = results.one()
+        print("Hero:", hero)
+
+        hero.age = 16
+        session.add(hero)
+        session.commit()
+        session.refresh(hero)
+        print("Updated hero:", hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/update/tutorial002.py b/docs_src/tutorial/update/tutorial002.py
new file mode 100644 (file)
index 0000000..04185f8
--- /dev/null
@@ -0,0 +1,65 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")  # (1)
+        results = session.exec(statement)  # (2)
+        hero = results.one()  # (3)
+        print("Hero:", hero)  # (4)
+
+        hero.age = 16  # (5)
+        session.add(hero)  # (6)
+        session.commit()  # (7)
+        session.refresh(hero)  # (8)
+        print("Updated hero:", hero)  # (9)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/update/tutorial003.py b/docs_src/tutorial/update/tutorial003.py
new file mode 100644 (file)
index 0000000..c319915
--- /dev/null
@@ -0,0 +1,79 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")
+        results = session.exec(statement)
+        hero_1 = results.one()
+        print("Hero 1:", hero_1)
+
+        statement = select(Hero).where(Hero.name == "Captain North America")
+        results = session.exec(statement)
+        hero_2 = results.one()
+        print("Hero 2:", hero_2)
+
+        hero_1.age = 16
+        hero_1.name = "Spider-Youngster"
+        session.add(hero_1)
+
+        hero_2.name = "Captain North America Except Canada"
+        hero_2.age = 110
+        session.add(hero_2)
+
+        session.commit()
+        session.refresh(hero_1)
+        session.refresh(hero_2)
+
+        print("Updated hero 1:", hero_1)
+        print("Updated hero 2:", hero_2)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/update/tutorial004.py b/docs_src/tutorial/update/tutorial004.py
new file mode 100644 (file)
index 0000000..e61a04f
--- /dev/null
@@ -0,0 +1,80 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def update_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Spider-Boy")  # (1)
+        results = session.exec(statement)  # (2)
+        hero_1 = results.one()  # (3)
+        print("Hero 1:", hero_1)  # (4)
+
+        statement = select(Hero).where(Hero.name == "Captain North America")  # (5)
+        results = session.exec(statement)  # (6)
+        hero_2 = results.one()  # (7)
+        print("Hero 2:", hero_2)  # (8)
+
+        hero_1.age = 16  # (9)
+        hero_1.name = "Spider-Youngster"  # (10)
+        session.add(hero_1)  # (11)
+
+        hero_2.name = "Captain North America Except Canada"  # (12)
+        hero_2.age = 110  # (13)
+        session.add(hero_2)  # (14)
+
+        session.commit()  # (15)
+        session.refresh(hero_1)  # (16)
+        session.refresh(hero_2)  # (17)
+
+        print("Updated hero 1:", hero_1)  # (18)
+        print("Updated hero 2:", hero_2)  # (19)
+    # (20)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    update_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/__init__.py b/docs_src/tutorial/where/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/tutorial/where/tutorial001.py b/docs_src/tutorial/where/tutorial001.py
new file mode 100644 (file)
index 0000000..71fcbc2
--- /dev/null
@@ -0,0 +1,51 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name == "Deadpond")
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial002.py b/docs_src/tutorial/where/tutorial002.py
new file mode 100644 (file)
index 0000000..7e34448
--- /dev/null
@@ -0,0 +1,51 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.name != "Deadpond")
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial003.py b/docs_src/tutorial/where/tutorial003.py
new file mode 100644 (file)
index 0000000..2aa31cc
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age > 35)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial004.py b/docs_src/tutorial/where/tutorial004.py
new file mode 100644 (file)
index 0000000..eeec6aa
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age >= 35)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial005.py b/docs_src/tutorial/where/tutorial005.py
new file mode 100644 (file)
index 0000000..505663e
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age < 35)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial006.py b/docs_src/tutorial/where/tutorial006.py
new file mode 100644 (file)
index 0000000..91bbca5
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age <= 35)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial007.py b/docs_src/tutorial/where/tutorial007.py
new file mode 100644 (file)
index 0000000..97250b5
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age >= 35).where(Hero.age < 40)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial008.py b/docs_src/tutorial/where/tutorial008.py
new file mode 100644 (file)
index 0000000..41d2ae6
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(Hero.age >= 35, Hero.age < 40)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial009.py b/docs_src/tutorial/where/tutorial009.py
new file mode 100644 (file)
index 0000000..9f69d65
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, or_, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(or_(Hero.age <= 35, Hero.age > 90))
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial010.py b/docs_src/tutorial/where/tutorial010.py
new file mode 100644 (file)
index 0000000..c35eb2c
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where((Hero.age <= 35) | (Hero.age > 90))
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()
diff --git a/docs_src/tutorial/where/tutorial011.py b/docs_src/tutorial/where/tutorial011.py
new file mode 100644 (file)
index 0000000..e365a3a
--- /dev/null
@@ -0,0 +1,59 @@
+from typing import Optional
+
+from sqlmodel import Field, Session, SQLModel, col, create_engine, select
+
+
+class Hero(SQLModel, table=True):
+    id: Optional[int] = Field(default=None, primary_key=True)
+    name: str
+    secret_name: str
+    age: Optional[int] = None
+
+
+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():
+    hero_1 = Hero(name="Deadpond", secret_name="Dive Wilson")
+    hero_2 = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
+    hero_3 = Hero(name="Rusty-Man", secret_name="Tommy Sharp", age=48)
+    hero_4 = Hero(name="Tarantula", secret_name="Natalia Roman-on", age=32)
+    hero_5 = Hero(name="Black Lion", secret_name="Trevor Challa", age=35)
+    hero_6 = Hero(name="Dr. Weird", secret_name="Steve Weird", age=36)
+    hero_7 = Hero(name="Captain North America", secret_name="Esteban Rogelios", age=93)
+
+    with Session(engine) as session:
+        session.add(hero_1)
+        session.add(hero_2)
+        session.add(hero_3)
+        session.add(hero_4)
+        session.add(hero_5)
+        session.add(hero_6)
+        session.add(hero_7)
+
+        session.commit()
+
+
+def select_heroes():
+    with Session(engine) as session:
+        statement = select(Hero).where(col(Hero.age) >= 35)
+        results = session.exec(statement)
+        for hero in results:
+            print(hero)
+
+
+def main():
+    create_db_and_tables()
+    create_heroes()
+    select_heroes()
+
+
+if __name__ == "__main__":
+    main()