{"owner":"fastapi","repo":"sqlmodel","hasSkills":true,"totalSkillsCount":1,"totalTokensCount":1827,"categories":["anthropic-skill"],"hasMcp":false,"mcpConfig":null,"found":["sqlmodel/.agents/skills/sqlmodel/SKILL.md"],"skills":{"sqlmodel/.agents/skills/sqlmodel/SKILL.md":"---\nname: sqlmodel\ndescription: Use when writing or reviewing Python code with SQLModel, especially models, sessions, queries, FastAPI integration, relationships, link models, creates, updates, and deletes.\n---\n\n# SQLModel Patterns\n\nUse SQLModel's API first. Do not default to raw SQLAlchemy patterns unless the task explicitly needs a SQLAlchemy-only feature.\n\n## Imports\n\nPrefer imports from `sqlmodel`:\n\n```python\nfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select\n```\n\nDo not use SQLAlchemy declarative defaults such as `declarative_base()`, `Mapped[...]`, `mapped_column()`, `relationship()`, or `sessionmaker()` for normal SQLModel code.\n\n## Models\n\nDefine table models with `SQLModel, table=True` and `Field()`:\n\n```python\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    name: str = Field(index=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n```\n\nUse `Field(default_factory=...)` for generated values:\n\n```python\nid: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)\n```\n\nUse non-table `SQLModel` classes for create/update/public API schemas instead of mixing request/response-only fields into table models.\n\n## Datetimes\n\nIn SQLModel `0.0.45` and newer, use `datetime` for timestamp fields. SQLModel automatically selects `UTCDateTime`, which normalizes aware values to UTC when writing and returns aware UTC datetimes when reading, including with SQLite and MySQL/MariaDB.\n\nDo not add `sa_type=DateTime(timezone=True)` or `sa_column=Column(DateTime(timezone=True))` just to enable timezone support. These overrides bypass SQLModel's UTC processing. If an explicit column type is needed, import `UTCDateTime` from `sqlmodel`.\n\nFor generated timestamps on Python 3.11 and newer:\n\n```python\nfrom datetime import UTC, datetime\n\nfrom sqlmodel import Field, SQLModel\n\n\nclass Event(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))\n```\n\nOn Python 3.10, import `timezone` instead of `UTC` and use `lambda: datetime.now(timezone.utc)`.\n\n- Supply aware datetimes for writes, updates, and query filters. Avoid `datetime.now()` without a timezone and `datetime.utcnow()` for UTC timestamps. Naive database parameters are rejected when the statement executes.\n- Use Pydantic's `AwareDatetime` when input validation must reject naive values. It uses the same UTC storage. Validate table-model input with `Model.model_validate(data)`. Direct table-model construction currently skips Pydantic validation, and plain `datetime` validation accepts naive values.\n- Use Pydantic's `NaiveDatetime` for intentional naive storage. It selects `DateTime(timezone=False)` and requires naive values during Pydantic validation.\n\nWhen upgrading existing applications, follow the [datetime migration guide](https://sqlmodel.tiangolo.com/advanced/datetime/#upgrade-existing-applications). Changing the model does not alter existing columns or convert historical data.\n\n## Sessions and Queries\n\nOpen sessions directly with the engine:\n\n```python\nwith Session(engine) as session:\n    heroes = session.exec(select(Hero)).all()\n```\n\nDo not create a `sessionmaker()` for typical SQLModel examples.\n\nUse `session.exec(select(...))`, not `session.execute(...)` and not `session.query(...)`. SQLModel's `exec()` handles scalar results so agents should not add `.scalars()` after selects of models.\n\nUse `session.get(Model, id)` for primary-key lookups.\n\nUse normal result methods after `session.exec(...)`: `.all()` for lists, `.first()` for optional first rows, `.one()` when exactly one row must exist, and `.one_or_none()` when zero or one row is valid.\n\nAfter creating or mutating objects, commit and refresh when returned data needs DB defaults or generated IDs:\n\n```python\nsession.add(hero)\nsession.commit()\nsession.refresh(hero)\n```\n\n## Relationships\n\nUse SQLModel relationship attributes, not ad-hoc SQLAlchemy tables or `secondary=`.\n\nOne-to-many:\n\n```python\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"team\")\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n    team: Team | None = Relationship(back_populates=\"heroes\")\n```\n\nMany-to-many:\n\n```python\nclass HeroTeamLink(SQLModel, table=True):\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\", primary_key=True)\n    hero_id: int | None = Field(default=None, foreign_key=\"hero.id\", primary_key=True)\n\n\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"teams\", link_model=HeroTeamLink)\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    teams: list[Team] = Relationship(back_populates=\"heroes\", link_model=HeroTeamLink)\n```\n\nIf the link table has extra fields, model it as a full SQLModel table with relationships to both sides, and interact with the link objects directly.\n\nWhen starting a new app, prefer keeping related SQLModel table models in one file to simplify relationship annotations and metadata ordering. If models must be split across files, use `TYPE_CHECKING` imports plus string annotations:\n\n```python\nif TYPE_CHECKING:\n    from .team_model import Team\n\nteam: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n```\n\nFor SQLAlchemy relationship options not exposed as first-class SQLModel parameters, prefer `Relationship(sa_relationship_kwargs={...})` or `Relationship(sa_relationship_args=[...])`. Use `sa_relationship=relationship(...)` only as an escape hatch when SQLModel's relationship wrapper cannot express the mapping.\n\n## Creates and Updates\n\nUse direct construction for trusted internal values:\n\n```python\nhero = Hero(name=\"Deadpond\", secret_name=\"Dive Wilson\")\n```\n\nBuild table objects from data models with `Model.model_validate(...)`:\n\n```python\ndb_hero = Hero.model_validate(hero_create)\n```\n\nFor FastAPI, use a split model pattern: `HeroBase` for shared fields, `Hero(HeroBase, table=True)` for the table, `HeroCreate` for input, `HeroUpdate` with all-optional fields for PATCH, `HeroPublic` for output, and relationship-specific public models such as `HeroPublicWithTeam` only where needed.\n\nFor partial updates, dump only provided fields and update in place:\n\n```python\nhero_data = hero_update.model_dump(exclude_unset=True)\ndb_hero.sqlmodel_update(hero_data)\nsession.add(db_hero)\nsession.commit()\nsession.refresh(db_hero)\n```\n\n## Metadata and App Setup\n\nCall `SQLModel.metadata.create_all(engine)` only after all table model classes have been imported. In FastAPI examples, use a dependency that yields `Session(engine)`.\n\nFor tests and small examples, SQLite is a common option; when using it, create metadata explicitly and use direct sessions:\n\n```python\nengine = create_engine(\"sqlite:///:memory:\")\nSQLModel.metadata.create_all(engine)\nwith Session(engine) as session:\n    ...\n```\n\nWhen using SQLite with FastAPI, include:\n\n```python\nconnect_args = {\"check_same_thread\": False}\nengine = create_engine(sqlite_url, connect_args=connect_args)\n```\n\n## Deletes\n\nUse SQLModel's relationship helpers for cascades:\n\n```python\nheroes: list[\"Hero\"] = Relationship(back_populates=\"team\", cascade_delete=True)\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"CASCADE\")\n```\n\nFor database-level delete behavior such as `SET NULL`, pair `ondelete` with a nullable foreign key and use `passive_deletes` on the relationship when appropriate.\n\n`ondelete=\"SET NULL\"` requires a nullable foreign key:\n\n```python\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"SET NULL\")\n```\n\n## SQLAlchemy Escape Hatches\n\nUse SQLModel's `Field(sa_type=...)`, `Field(sa_column=...)`, `Field(sa_column_args=...)`, or `Field(sa_column_kwargs=...)` only when normal `Field()` parameters do not cover a column or type requirement. Do not switch the whole model to SQLAlchemy declarative style for one custom column.\n"},"files":{"sqlmodel/.agents/skills/sqlmodel/SKILL.md":"---\nname: sqlmodel\ndescription: Use when writing or reviewing Python code with SQLModel, especially models, sessions, queries, FastAPI integration, relationships, link models, creates, updates, and deletes.\n---\n\n# SQLModel Patterns\n\nUse SQLModel's API first. Do not default to raw SQLAlchemy patterns unless the task explicitly needs a SQLAlchemy-only feature.\n\n## Imports\n\nPrefer imports from `sqlmodel`:\n\n```python\nfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select\n```\n\nDo not use SQLAlchemy declarative defaults such as `declarative_base()`, `Mapped[...]`, `mapped_column()`, `relationship()`, or `sessionmaker()` for normal SQLModel code.\n\n## Models\n\nDefine table models with `SQLModel, table=True` and `Field()`:\n\n```python\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    name: str = Field(index=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n```\n\nUse `Field(default_factory=...)` for generated values:\n\n```python\nid: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)\n```\n\nUse non-table `SQLModel` classes for create/update/public API schemas instead of mixing request/response-only fields into table models.\n\n## Datetimes\n\nIn SQLModel `0.0.45` and newer, use `datetime` for timestamp fields. SQLModel automatically selects `UTCDateTime`, which normalizes aware values to UTC when writing and returns aware UTC datetimes when reading, including with SQLite and MySQL/MariaDB.\n\nDo not add `sa_type=DateTime(timezone=True)` or `sa_column=Column(DateTime(timezone=True))` just to enable timezone support. These overrides bypass SQLModel's UTC processing. If an explicit column type is needed, import `UTCDateTime` from `sqlmodel`.\n\nFor generated timestamps on Python 3.11 and newer:\n\n```python\nfrom datetime import UTC, datetime\n\nfrom sqlmodel import Field, SQLModel\n\n\nclass Event(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))\n```\n\nOn Python 3.10, import `timezone` instead of `UTC` and use `lambda: datetime.now(timezone.utc)`.\n\n- Supply aware datetimes for writes, updates, and query filters. Avoid `datetime.now()` without a timezone and `datetime.utcnow()` for UTC timestamps. Naive database parameters are rejected when the statement executes.\n- Use Pydantic's `AwareDatetime` when input validation must reject naive values. It uses the same UTC storage. Validate table-model input with `Model.model_validate(data)`. Direct table-model construction currently skips Pydantic validation, and plain `datetime` validation accepts naive values.\n- Use Pydantic's `NaiveDatetime` for intentional naive storage. It selects `DateTime(timezone=False)` and requires naive values during Pydantic validation.\n\nWhen upgrading existing applications, follow the [datetime migration guide](https://sqlmodel.tiangolo.com/advanced/datetime/#upgrade-existing-applications). Changing the model does not alter existing columns or convert historical data.\n\n## Sessions and Queries\n\nOpen sessions directly with the engine:\n\n```python\nwith Session(engine) as session:\n    heroes = session.exec(select(Hero)).all()\n```\n\nDo not create a `sessionmaker()` for typical SQLModel examples.\n\nUse `session.exec(select(...))`, not `session.execute(...)` and not `session.query(...)`. SQLModel's `exec()` handles scalar results so agents should not add `.scalars()` after selects of models.\n\nUse `session.get(Model, id)` for primary-key lookups.\n\nUse normal result methods after `session.exec(...)`: `.all()` for lists, `.first()` for optional first rows, `.one()` when exactly one row must exist, and `.one_or_none()` when zero or one row is valid.\n\nAfter creating or mutating objects, commit and refresh when returned data needs DB defaults or generated IDs:\n\n```python\nsession.add(hero)\nsession.commit()\nsession.refresh(hero)\n```\n\n## Relationships\n\nUse SQLModel relationship attributes, not ad-hoc SQLAlchemy tables or `secondary=`.\n\nOne-to-many:\n\n```python\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"team\")\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n    team: Team | None = Relationship(back_populates=\"heroes\")\n```\n\nMany-to-many:\n\n```python\nclass HeroTeamLink(SQLModel, table=True):\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\", primary_key=True)\n    hero_id: int | None = Field(default=None, foreign_key=\"hero.id\", primary_key=True)\n\n\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"teams\", link_model=HeroTeamLink)\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    teams: list[Team] = Relationship(back_populates=\"heroes\", link_model=HeroTeamLink)\n```\n\nIf the link table has extra fields, model it as a full SQLModel table with relationships to both sides, and interact with the link objects directly.\n\nWhen starting a new app, prefer keeping related SQLModel table models in one file to simplify relationship annotations and metadata ordering. If models must be split across files, use `TYPE_CHECKING` imports plus string annotations:\n\n```python\nif TYPE_CHECKING:\n    from .team_model import Team\n\nteam: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n```\n\nFor SQLAlchemy relationship options not exposed as first-class SQLModel parameters, prefer `Relationship(sa_relationship_kwargs={...})` or `Relationship(sa_relationship_args=[...])`. Use `sa_relationship=relationship(...)` only as an escape hatch when SQLModel's relationship wrapper cannot express the mapping.\n\n## Creates and Updates\n\nUse direct construction for trusted internal values:\n\n```python\nhero = Hero(name=\"Deadpond\", secret_name=\"Dive Wilson\")\n```\n\nBuild table objects from data models with `Model.model_validate(...)`:\n\n```python\ndb_hero = Hero.model_validate(hero_create)\n```\n\nFor FastAPI, use a split model pattern: `HeroBase` for shared fields, `Hero(HeroBase, table=True)` for the table, `HeroCreate` for input, `HeroUpdate` with all-optional fields for PATCH, `HeroPublic` for output, and relationship-specific public models such as `HeroPublicWithTeam` only where needed.\n\nFor partial updates, dump only provided fields and update in place:\n\n```python\nhero_data = hero_update.model_dump(exclude_unset=True)\ndb_hero.sqlmodel_update(hero_data)\nsession.add(db_hero)\nsession.commit()\nsession.refresh(db_hero)\n```\n\n## Metadata and App Setup\n\nCall `SQLModel.metadata.create_all(engine)` only after all table model classes have been imported. In FastAPI examples, use a dependency that yields `Session(engine)`.\n\nFor tests and small examples, SQLite is a common option; when using it, create metadata explicitly and use direct sessions:\n\n```python\nengine = create_engine(\"sqlite:///:memory:\")\nSQLModel.metadata.create_all(engine)\nwith Session(engine) as session:\n    ...\n```\n\nWhen using SQLite with FastAPI, include:\n\n```python\nconnect_args = {\"check_same_thread\": False}\nengine = create_engine(sqlite_url, connect_args=connect_args)\n```\n\n## Deletes\n\nUse SQLModel's relationship helpers for cascades:\n\n```python\nheroes: list[\"Hero\"] = Relationship(back_populates=\"team\", cascade_delete=True)\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"CASCADE\")\n```\n\nFor database-level delete behavior such as `SET NULL`, pair `ondelete` with a nullable foreign key and use `passive_deletes` on the relationship when appropriate.\n\n`ondelete=\"SET NULL\"` requires a nullable foreign key:\n\n```python\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"SET NULL\")\n```\n\n## SQLAlchemy Escape Hatches\n\nUse SQLModel's `Field(sa_type=...)`, `Field(sa_column=...)`, `Field(sa_column_args=...)`, or `Field(sa_column_kwargs=...)` only when normal `Field()` parameters do not cover a column or type requirement. Do not switch the whole model to SQLAlchemy declarative style for one custom column.\n"},"items":[{"name":"SKILL.md","path":"sqlmodel/.agents/skills/sqlmodel/SKILL.md","rawUrl":"https://raw.githubusercontent.com/fastapi/sqlmodel/HEAD/sqlmodel/.agents/skills/sqlmodel/SKILL.md","title":"sqlmodel","category":"anthropic-skill","format":"markdown","content":"---\nname: sqlmodel\ndescription: Use when writing or reviewing Python code with SQLModel, especially models, sessions, queries, FastAPI integration, relationships, link models, creates, updates, and deletes.\n---\n\n# SQLModel Patterns\n\nUse SQLModel's API first. Do not default to raw SQLAlchemy patterns unless the task explicitly needs a SQLAlchemy-only feature.\n\n## Imports\n\nPrefer imports from `sqlmodel`:\n\n```python\nfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select\n```\n\nDo not use SQLAlchemy declarative defaults such as `declarative_base()`, `Mapped[...]`, `mapped_column()`, `relationship()`, or `sessionmaker()` for normal SQLModel code.\n\n## Models\n\nDefine table models with `SQLModel, table=True` and `Field()`:\n\n```python\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    name: str = Field(index=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n```\n\nUse `Field(default_factory=...)` for generated values:\n\n```python\nid: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)\n```\n\nUse non-table `SQLModel` classes for create/update/public API schemas instead of mixing request/response-only fields into table models.\n\n## Datetimes\n\nIn SQLModel `0.0.45` and newer, use `datetime` for timestamp fields. SQLModel automatically selects `UTCDateTime`, which normalizes aware values to UTC when writing and returns aware UTC datetimes when reading, including with SQLite and MySQL/MariaDB.\n\nDo not add `sa_type=DateTime(timezone=True)` or `sa_column=Column(DateTime(timezone=True))` just to enable timezone support. These overrides bypass SQLModel's UTC processing. If an explicit column type is needed, import `UTCDateTime` from `sqlmodel`.\n\nFor generated timestamps on Python 3.11 and newer:\n\n```python\nfrom datetime import UTC, datetime\n\nfrom sqlmodel import Field, SQLModel\n\n\nclass Event(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))\n```\n\nOn Python 3.10, import `timezone` instead of `UTC` and use `lambda: datetime.now(timezone.utc)`.\n\n- Supply aware datetimes for writes, updates, and query filters. Avoid `datetime.now()` without a timezone and `datetime.utcnow()` for UTC timestamps. Naive database parameters are rejected when the statement executes.\n- Use Pydantic's `AwareDatetime` when input validation must reject naive values. It uses the same UTC storage. Validate table-model input with `Model.model_validate(data)`. Direct table-model construction currently skips Pydantic validation, and plain `datetime` validation accepts naive values.\n- Use Pydantic's `NaiveDatetime` for intentional naive storage. It selects `DateTime(timezone=False)` and requires naive values during Pydantic validation.\n\nWhen upgrading existing applications, follow the [datetime migration guide](https://sqlmodel.tiangolo.com/advanced/datetime/#upgrade-existing-applications). Changing the model does not alter existing columns or convert historical data.\n\n## Sessions and Queries\n\nOpen sessions directly with the engine:\n\n```python\nwith Session(engine) as session:\n    heroes = session.exec(select(Hero)).all()\n```\n\nDo not create a `sessionmaker()` for typical SQLModel examples.\n\nUse `session.exec(select(...))`, not `session.execute(...)` and not `session.query(...)`. SQLModel's `exec()` handles scalar results so agents should not add `.scalars()` after selects of models.\n\nUse `session.get(Model, id)` for primary-key lookups.\n\nUse normal result methods after `session.exec(...)`: `.all()` for lists, `.first()` for optional first rows, `.one()` when exactly one row must exist, and `.one_or_none()` when zero or one row is valid.\n\nAfter creating or mutating objects, commit and refresh when returned data needs DB defaults or generated IDs:\n\n```python\nsession.add(hero)\nsession.commit()\nsession.refresh(hero)\n```\n\n## Relationships\n\nUse SQLModel relationship attributes, not ad-hoc SQLAlchemy tables or `secondary=`.\n\nOne-to-many:\n\n```python\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"team\")\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n    team: Team | None = Relationship(back_populates=\"heroes\")\n```\n\nMany-to-many:\n\n```python\nclass HeroTeamLink(SQLModel, table=True):\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\", primary_key=True)\n    hero_id: int | None = Field(default=None, foreign_key=\"hero.id\", primary_key=True)\n\n\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"teams\", link_model=HeroTeamLink)\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    teams: list[Team] = Relationship(back_populates=\"heroes\", link_model=HeroTeamLink)\n```\n\nIf the link table has extra fields, model it as a full SQLModel table with relationships to both sides, and interact with the link objects directly.\n\nWhen starting a new app, prefer keeping related SQLModel table models in one file to simplify relationship annotations and metadata ordering. If models must be split across files, use `TYPE_CHECKING` imports plus string annotations:\n\n```python\nif TYPE_CHECKING:\n    from .team_model import Team\n\nteam: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n```\n\nFor SQLAlchemy relationship options not exposed as first-class SQLModel parameters, prefer `Relationship(sa_relationship_kwargs={...})` or `Relationship(sa_relationship_args=[...])`. Use `sa_relationship=relationship(...)` only as an escape hatch when SQLModel's relationship wrapper cannot express the mapping.\n\n## Creates and Updates\n\nUse direct construction for trusted internal values:\n\n```python\nhero = Hero(name=\"Deadpond\", secret_name=\"Dive Wilson\")\n```\n\nBuild table objects from data models with `Model.model_validate(...)`:\n\n```python\ndb_hero = Hero.model_validate(hero_create)\n```\n\nFor FastAPI, use a split model pattern: `HeroBase` for shared fields, `Hero(HeroBase, table=True)` for the table, `HeroCreate` for input, `HeroUpdate` with all-optional fields for PATCH, `HeroPublic` for output, and relationship-specific public models such as `HeroPublicWithTeam` only where needed.\n\nFor partial updates, dump only provided fields and update in place:\n\n```python\nhero_data = hero_update.model_dump(exclude_unset=True)\ndb_hero.sqlmodel_update(hero_data)\nsession.add(db_hero)\nsession.commit()\nsession.refresh(db_hero)\n```\n\n## Metadata and App Setup\n\nCall `SQLModel.metadata.create_all(engine)` only after all table model classes have been imported. In FastAPI examples, use a dependency that yields `Session(engine)`.\n\nFor tests and small examples, SQLite is a common option; when using it, create metadata explicitly and use direct sessions:\n\n```python\nengine = create_engine(\"sqlite:///:memory:\")\nSQLModel.metadata.create_all(engine)\nwith Session(engine) as session:\n    ...\n```\n\nWhen using SQLite with FastAPI, include:\n\n```python\nconnect_args = {\"check_same_thread\": False}\nengine = create_engine(sqlite_url, connect_args=connect_args)\n```\n\n## Deletes\n\nUse SQLModel's relationship helpers for cascades:\n\n```python\nheroes: list[\"Hero\"] = Relationship(back_populates=\"team\", cascade_delete=True)\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"CASCADE\")\n```\n\nFor database-level delete behavior such as `SET NULL`, pair `ondelete` with a nullable foreign key and use `passive_deletes` on the relationship when appropriate.\n\n`ondelete=\"SET NULL\"` requires a nullable foreign key:\n\n```python\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"SET NULL\")\n```\n\n## SQLAlchemy Escape Hatches\n\nUse SQLModel's `Field(sa_type=...)`, `Field(sa_column=...)`, `Field(sa_column_args=...)`, or `Field(sa_column_kwargs=...)` only when normal `Field()` parameters do not cover a column or type requirement. Do not switch the whole model to SQLAlchemy declarative style for one custom column.\n","frontmatter":{"name":"sqlmodel","description":"Use when writing or reviewing Python code with SQLModel, especially models, sessions, queries, FastAPI integration, relationships, link models, creates, updates, and deletes."},"isInternal":false,"tokens":1827,"sizeBytes":8216}],"systemPromptSnippet":"<yakaai_skills repo=\"fastapi/sqlmodel\">\n<!-- File: sqlmodel/.agents/skills/sqlmodel/SKILL.md (Tokens: ~1827 | Category: anthropic-skill) -->\n---\nname: sqlmodel\ndescription: Use when writing or reviewing Python code with SQLModel, especially models, sessions, queries, FastAPI integration, relationships, link models, creates, updates, and deletes.\n---\n\n# SQLModel Patterns\n\nUse SQLModel's API first. Do not default to raw SQLAlchemy patterns unless the task explicitly needs a SQLAlchemy-only feature.\n\n## Imports\n\nPrefer imports from `sqlmodel`:\n\n```python\nfrom sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select\n```\n\nDo not use SQLAlchemy declarative defaults such as `declarative_base()`, `Mapped[...]`, `mapped_column()`, `relationship()`, or `sessionmaker()` for normal SQLModel code.\n\n## Models\n\nDefine table models with `SQLModel, table=True` and `Field()`:\n\n```python\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    name: str = Field(index=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n```\n\nUse `Field(default_factory=...)` for generated values:\n\n```python\nid: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)\n```\n\nUse non-table `SQLModel` classes for create/update/public API schemas instead of mixing request/response-only fields into table models.\n\n## Datetimes\n\nIn SQLModel `0.0.45` and newer, use `datetime` for timestamp fields. SQLModel automatically selects `UTCDateTime`, which normalizes aware values to UTC when writing and returns aware UTC datetimes when reading, including with SQLite and MySQL/MariaDB.\n\nDo not add `sa_type=DateTime(timezone=True)` or `sa_column=Column(DateTime(timezone=True))` just to enable timezone support. These overrides bypass SQLModel's UTC processing. If an explicit column type is needed, import `UTCDateTime` from `sqlmodel`.\n\nFor generated timestamps on Python 3.11 and newer:\n\n```python\nfrom datetime import UTC, datetime\n\nfrom sqlmodel import Field, SQLModel\n\n\nclass Event(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    created_at: datetime = Field(default_factory=lambda: datetime.now(UTC))\n```\n\nOn Python 3.10, import `timezone` instead of `UTC` and use `lambda: datetime.now(timezone.utc)`.\n\n- Supply aware datetimes for writes, updates, and query filters. Avoid `datetime.now()` without a timezone and `datetime.utcnow()` for UTC timestamps. Naive database parameters are rejected when the statement executes.\n- Use Pydantic's `AwareDatetime` when input validation must reject naive values. It uses the same UTC storage. Validate table-model input with `Model.model_validate(data)`. Direct table-model construction currently skips Pydantic validation, and plain `datetime` validation accepts naive values.\n- Use Pydantic's `NaiveDatetime` for intentional naive storage. It selects `DateTime(timezone=False)` and requires naive values during Pydantic validation.\n\nWhen upgrading existing applications, follow the [datetime migration guide](https://sqlmodel.tiangolo.com/advanced/datetime/#upgrade-existing-applications). Changing the model does not alter existing columns or convert historical data.\n\n## Sessions and Queries\n\nOpen sessions directly with the engine:\n\n```python\nwith Session(engine) as session:\n    heroes = session.exec(select(Hero)).all()\n```\n\nDo not create a `sessionmaker()` for typical SQLModel examples.\n\nUse `session.exec(select(...))`, not `session.execute(...)` and not `session.query(...)`. SQLModel's `exec()` handles scalar results so agents should not add `.scalars()` after selects of models.\n\nUse `session.get(Model, id)` for primary-key lookups.\n\nUse normal result methods after `session.exec(...)`: `.all()` for lists, `.first()` for optional first rows, `.one()` when exactly one row must exist, and `.one_or_none()` when zero or one row is valid.\n\nAfter creating or mutating objects, commit and refresh when returned data needs DB defaults or generated IDs:\n\n```python\nsession.add(hero)\nsession.commit()\nsession.refresh(hero)\n```\n\n## Relationships\n\nUse SQLModel relationship attributes, not ad-hoc SQLAlchemy tables or `secondary=`.\n\nOne-to-many:\n\n```python\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"team\")\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n    team: Team | None = Relationship(back_populates=\"heroes\")\n```\n\nMany-to-many:\n\n```python\nclass HeroTeamLink(SQLModel, table=True):\n    team_id: int | None = Field(default=None, foreign_key=\"team.id\", primary_key=True)\n    hero_id: int | None = Field(default=None, foreign_key=\"hero.id\", primary_key=True)\n\n\nclass Team(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    heroes: list[\"Hero\"] = Relationship(back_populates=\"teams\", link_model=HeroTeamLink)\n\n\nclass Hero(SQLModel, table=True):\n    id: int | None = Field(default=None, primary_key=True)\n    teams: list[Team] = Relationship(back_populates=\"heroes\", link_model=HeroTeamLink)\n```\n\nIf the link table has extra fields, model it as a full SQLModel table with relationships to both sides, and interact with the link objects directly.\n\nWhen starting a new app, prefer keeping related SQLModel table models in one file to simplify relationship annotations and metadata ordering. If models must be split across files, use `TYPE_CHECKING` imports plus string annotations:\n\n```python\nif TYPE_CHECKING:\n    from .team_model import Team\n\nteam: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n```\n\nFor SQLAlchemy relationship options not exposed as first-class SQLModel parameters, prefer `Relationship(sa_relationship_kwargs={...})` or `Relationship(sa_relationship_args=[...])`. Use `sa_relationship=relationship(...)` only as an escape hatch when SQLModel's relationship wrapper cannot express the mapping.\n\n## Creates and Updates\n\nUse direct construction for trusted internal values:\n\n```python\nhero = Hero(name=\"Deadpond\", secret_name=\"Dive Wilson\")\n```\n\nBuild table objects from data models with `Model.model_validate(...)`:\n\n```python\ndb_hero = Hero.model_validate(hero_create)\n```\n\nFor FastAPI, use a split model pattern: `HeroBase` for shared fields, `Hero(HeroBase, table=True)` for the table, `HeroCreate` for input, `HeroUpdate` with all-optional fields for PATCH, `HeroPublic` for output, and relationship-specific public models such as `HeroPublicWithTeam` only where needed.\n\nFor partial updates, dump only provided fields and update in place:\n\n```python\nhero_data = hero_update.model_dump(exclude_unset=True)\ndb_hero.sqlmodel_update(hero_data)\nsession.add(db_hero)\nsession.commit()\nsession.refresh(db_hero)\n```\n\n## Metadata and App Setup\n\nCall `SQLModel.metadata.create_all(engine)` only after all table model classes have been imported. In FastAPI examples, use a dependency that yields `Session(engine)`.\n\nFor tests and small examples, SQLite is a common option; when using it, create metadata explicitly and use direct sessions:\n\n```python\nengine = create_engine(\"sqlite:///:memory:\")\nSQLModel.metadata.create_all(engine)\nwith Session(engine) as session:\n    ...\n```\n\nWhen using SQLite with FastAPI, include:\n\n```python\nconnect_args = {\"check_same_thread\": False}\nengine = create_engine(sqlite_url, connect_args=connect_args)\n```\n\n## Deletes\n\nUse SQLModel's relationship helpers for cascades:\n\n```python\nheroes: list[\"Hero\"] = Relationship(back_populates=\"team\", cascade_delete=True)\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"CASCADE\")\n```\n\nFor database-level delete behavior such as `SET NULL`, pair `ondelete` with a nullable foreign key and use `passive_deletes` on the relationship when appropriate.\n\n`ondelete=\"SET NULL\"` requires a nullable foreign key:\n\n```python\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"SET NULL\")\n```\n\n## SQLAlchemy Escape Hatches\n\nUse SQLModel's `Field(sa_type=...)`, `Field(sa_column=...)`, `Field(sa_column_args=...)`, or `Field(sa_column_kwargs=...)` only when normal `Field()` parameters do not cover a column or type requirement. Do not switch the whole model to SQLAlchemy declarative style for one custom column.\n</yakaai_skills>"}