[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-fastapi-sqlmodel":3,"mdc--j34j8z-key":43,"related-repo-fastapi-sqlmodel":1130,"related-org-fastapi-sqlmodel":1141},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":11,"stars":28,"repoUrl":29,"updatedAt":30,"license":31,"forks":32,"topics":33,"repo":38,"sourceUrl":41,"mdContent":42},"sqlmodel","build and manage databases with SQLModel","Use when writing or reviewing Python code with SQLModel, especially models, sessions, queries, FastAPI integration, relationships, link models, creates, updates, and deletes.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},"fastapi","FastAPI","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Ffastapi.png",[12,15,18,21,24,27],{"name":13,"slug":4,"type":14},"SQLModel","tag",{"name":16,"slug":17,"type":14},"Database","database",{"name":19,"slug":20,"type":14},"ORM","orm",{"name":22,"slug":23,"type":14},"Python","python",{"name":25,"slug":26,"type":14},"SQL","sql",{"name":9,"slug":8,"type":14},18266,"https:\u002F\u002Fgithub.com\u002Ffastapi\u002Fsqlmodel","2026-09-01T08:30:37.656498",null,884,[8,34,35,36,23,26,37],"json","json-schema","pydantic","sqlalchemy",{"repoUrl":29,"stars":28,"forks":32,"topics":39,"description":40},[8,34,35,36,23,26,37],"SQL databases in Python, designed for simplicity, compatibility, and robustness.","https:\u002F\u002Fgithub.com\u002Ffastapi\u002Fsqlmodel\u002Ftree\u002FHEAD\u002Fsqlmodel\u002F.agents\u002Fskills\u002Fsqlmodel","---\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\u002Fupdate\u002Fpublic API schemas instead of mixing request\u002Fresponse-only fields into table models.\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:\u002F\u002F\u002F: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",{"data":44,"body":45},{"name":4,"description":6},{"type":46,"children":47},"root",[48,57,63,70,83,103,146,152,172,214,227,241,253,259,264,287,299,343,355,400,405,436,442,455,460,540,545,652,657,670,708,737,743,748,762,774,788,841,846,892,898,918,923,961,966,989,995,1000,1023,1052,1063,1077,1083,1124],{"type":49,"tag":50,"props":51,"children":53},"element","h1",{"id":52},"sqlmodel-patterns",[54],{"type":55,"value":56},"text","SQLModel Patterns",{"type":49,"tag":58,"props":59,"children":60},"p",{},[61],{"type":55,"value":62},"Use SQLModel's API first. Do not default to raw SQLAlchemy patterns unless the task explicitly needs a SQLAlchemy-only feature.",{"type":49,"tag":64,"props":65,"children":67},"h2",{"id":66},"imports",[68],{"type":55,"value":69},"Imports",{"type":49,"tag":58,"props":71,"children":72},{},[73,75,81],{"type":55,"value":74},"Prefer imports from ",{"type":49,"tag":76,"props":77,"children":79},"code",{"className":78},[],[80],{"type":55,"value":4},{"type":55,"value":82},":",{"type":49,"tag":84,"props":85,"children":89},"pre",{"className":86,"code":87,"language":23,"meta":88,"style":88},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from sqlmodel import Field, Relationship, Session, SQLModel, create_engine, select\n","",[90],{"type":49,"tag":76,"props":91,"children":92},{"__ignoreMap":88},[93],{"type":49,"tag":94,"props":95,"children":98},"span",{"class":96,"line":97},"line",1,[99],{"type":49,"tag":94,"props":100,"children":101},{},[102],{"type":55,"value":87},{"type":49,"tag":58,"props":104,"children":105},{},[106,108,114,116,122,123,129,130,136,138,144],{"type":55,"value":107},"Do not use SQLAlchemy declarative defaults such as ",{"type":49,"tag":76,"props":109,"children":111},{"className":110},[],[112],{"type":55,"value":113},"declarative_base()",{"type":55,"value":115},", ",{"type":49,"tag":76,"props":117,"children":119},{"className":118},[],[120],{"type":55,"value":121},"Mapped[...]",{"type":55,"value":115},{"type":49,"tag":76,"props":124,"children":126},{"className":125},[],[127],{"type":55,"value":128},"mapped_column()",{"type":55,"value":115},{"type":49,"tag":76,"props":131,"children":133},{"className":132},[],[134],{"type":55,"value":135},"relationship()",{"type":55,"value":137},", or ",{"type":49,"tag":76,"props":139,"children":141},{"className":140},[],[142],{"type":55,"value":143},"sessionmaker()",{"type":55,"value":145}," for normal SQLModel code.",{"type":49,"tag":64,"props":147,"children":149},{"id":148},"models",[150],{"type":55,"value":151},"Models",{"type":49,"tag":58,"props":153,"children":154},{},[155,157,163,165,171],{"type":55,"value":156},"Define table models with ",{"type":49,"tag":76,"props":158,"children":160},{"className":159},[],[161],{"type":55,"value":162},"SQLModel, table=True",{"type":55,"value":164}," and ",{"type":49,"tag":76,"props":166,"children":168},{"className":167},[],[169],{"type":55,"value":170},"Field()",{"type":55,"value":82},{"type":49,"tag":84,"props":173,"children":175},{"className":86,"code":174,"language":23,"meta":88,"style":88},"class 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",[176],{"type":49,"tag":76,"props":177,"children":178},{"__ignoreMap":88},[179,187,196,205],{"type":49,"tag":94,"props":180,"children":181},{"class":96,"line":97},[182],{"type":49,"tag":94,"props":183,"children":184},{},[185],{"type":55,"value":186},"class Hero(SQLModel, table=True):\n",{"type":49,"tag":94,"props":188,"children":190},{"class":96,"line":189},2,[191],{"type":49,"tag":94,"props":192,"children":193},{},[194],{"type":55,"value":195},"    id: int | None = Field(default=None, primary_key=True)\n",{"type":49,"tag":94,"props":197,"children":199},{"class":96,"line":198},3,[200],{"type":49,"tag":94,"props":201,"children":202},{},[203],{"type":55,"value":204},"    name: str = Field(index=True)\n",{"type":49,"tag":94,"props":206,"children":208},{"class":96,"line":207},4,[209],{"type":49,"tag":94,"props":210,"children":211},{},[212],{"type":55,"value":213},"    team_id: int | None = Field(default=None, foreign_key=\"team.id\")\n",{"type":49,"tag":58,"props":215,"children":216},{},[217,219,225],{"type":55,"value":218},"Use ",{"type":49,"tag":76,"props":220,"children":222},{"className":221},[],[223],{"type":55,"value":224},"Field(default_factory=...)",{"type":55,"value":226}," for generated values:",{"type":49,"tag":84,"props":228,"children":230},{"className":86,"code":229,"language":23,"meta":88,"style":88},"id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True)\n",[231],{"type":49,"tag":76,"props":232,"children":233},{"__ignoreMap":88},[234],{"type":49,"tag":94,"props":235,"children":236},{"class":96,"line":97},[237],{"type":49,"tag":94,"props":238,"children":239},{},[240],{"type":55,"value":229},{"type":49,"tag":58,"props":242,"children":243},{},[244,246,251],{"type":55,"value":245},"Use non-table ",{"type":49,"tag":76,"props":247,"children":249},{"className":248},[],[250],{"type":55,"value":13},{"type":55,"value":252}," classes for create\u002Fupdate\u002Fpublic API schemas instead of mixing request\u002Fresponse-only fields into table models.",{"type":49,"tag":64,"props":254,"children":256},{"id":255},"sessions-and-queries",[257],{"type":55,"value":258},"Sessions and Queries",{"type":49,"tag":58,"props":260,"children":261},{},[262],{"type":55,"value":263},"Open sessions directly with the engine:",{"type":49,"tag":84,"props":265,"children":267},{"className":86,"code":266,"language":23,"meta":88,"style":88},"with Session(engine) as session:\n    heroes = session.exec(select(Hero)).all()\n",[268],{"type":49,"tag":76,"props":269,"children":270},{"__ignoreMap":88},[271,279],{"type":49,"tag":94,"props":272,"children":273},{"class":96,"line":97},[274],{"type":49,"tag":94,"props":275,"children":276},{},[277],{"type":55,"value":278},"with Session(engine) as session:\n",{"type":49,"tag":94,"props":280,"children":281},{"class":96,"line":189},[282],{"type":49,"tag":94,"props":283,"children":284},{},[285],{"type":55,"value":286},"    heroes = session.exec(select(Hero)).all()\n",{"type":49,"tag":58,"props":288,"children":289},{},[290,292,297],{"type":55,"value":291},"Do not create a ",{"type":49,"tag":76,"props":293,"children":295},{"className":294},[],[296],{"type":55,"value":143},{"type":55,"value":298}," for typical SQLModel examples.",{"type":49,"tag":58,"props":300,"children":301},{},[302,303,309,311,317,319,325,327,333,335,341],{"type":55,"value":218},{"type":49,"tag":76,"props":304,"children":306},{"className":305},[],[307],{"type":55,"value":308},"session.exec(select(...))",{"type":55,"value":310},", not ",{"type":49,"tag":76,"props":312,"children":314},{"className":313},[],[315],{"type":55,"value":316},"session.execute(...)",{"type":55,"value":318}," and not ",{"type":49,"tag":76,"props":320,"children":322},{"className":321},[],[323],{"type":55,"value":324},"session.query(...)",{"type":55,"value":326},". SQLModel's ",{"type":49,"tag":76,"props":328,"children":330},{"className":329},[],[331],{"type":55,"value":332},"exec()",{"type":55,"value":334}," handles scalar results so agents should not add ",{"type":49,"tag":76,"props":336,"children":338},{"className":337},[],[339],{"type":55,"value":340},".scalars()",{"type":55,"value":342}," after selects of models.",{"type":49,"tag":58,"props":344,"children":345},{},[346,347,353],{"type":55,"value":218},{"type":49,"tag":76,"props":348,"children":350},{"className":349},[],[351],{"type":55,"value":352},"session.get(Model, id)",{"type":55,"value":354}," for primary-key lookups.",{"type":49,"tag":58,"props":356,"children":357},{},[358,360,366,368,374,376,382,384,390,392,398],{"type":55,"value":359},"Use normal result methods after ",{"type":49,"tag":76,"props":361,"children":363},{"className":362},[],[364],{"type":55,"value":365},"session.exec(...)",{"type":55,"value":367},": ",{"type":49,"tag":76,"props":369,"children":371},{"className":370},[],[372],{"type":55,"value":373},".all()",{"type":55,"value":375}," for lists, ",{"type":49,"tag":76,"props":377,"children":379},{"className":378},[],[380],{"type":55,"value":381},".first()",{"type":55,"value":383}," for optional first rows, ",{"type":49,"tag":76,"props":385,"children":387},{"className":386},[],[388],{"type":55,"value":389},".one()",{"type":55,"value":391}," when exactly one row must exist, and ",{"type":49,"tag":76,"props":393,"children":395},{"className":394},[],[396],{"type":55,"value":397},".one_or_none()",{"type":55,"value":399}," when zero or one row is valid.",{"type":49,"tag":58,"props":401,"children":402},{},[403],{"type":55,"value":404},"After creating or mutating objects, commit and refresh when returned data needs DB defaults or generated IDs:",{"type":49,"tag":84,"props":406,"children":408},{"className":86,"code":407,"language":23,"meta":88,"style":88},"session.add(hero)\nsession.commit()\nsession.refresh(hero)\n",[409],{"type":49,"tag":76,"props":410,"children":411},{"__ignoreMap":88},[412,420,428],{"type":49,"tag":94,"props":413,"children":414},{"class":96,"line":97},[415],{"type":49,"tag":94,"props":416,"children":417},{},[418],{"type":55,"value":419},"session.add(hero)\n",{"type":49,"tag":94,"props":421,"children":422},{"class":96,"line":189},[423],{"type":49,"tag":94,"props":424,"children":425},{},[426],{"type":55,"value":427},"session.commit()\n",{"type":49,"tag":94,"props":429,"children":430},{"class":96,"line":198},[431],{"type":49,"tag":94,"props":432,"children":433},{},[434],{"type":55,"value":435},"session.refresh(hero)\n",{"type":49,"tag":64,"props":437,"children":439},{"id":438},"relationships",[440],{"type":55,"value":441},"Relationships",{"type":49,"tag":58,"props":443,"children":444},{},[445,447,453],{"type":55,"value":446},"Use SQLModel relationship attributes, not ad-hoc SQLAlchemy tables or ",{"type":49,"tag":76,"props":448,"children":450},{"className":449},[],[451],{"type":55,"value":452},"secondary=",{"type":55,"value":454},".",{"type":49,"tag":58,"props":456,"children":457},{},[458],{"type":55,"value":459},"One-to-many:",{"type":49,"tag":84,"props":461,"children":463},{"className":86,"code":462,"language":23,"meta":88,"style":88},"class 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",[464],{"type":49,"tag":76,"props":465,"children":466},{"__ignoreMap":88},[467,475,482,490,499,507,515,523,531],{"type":49,"tag":94,"props":468,"children":469},{"class":96,"line":97},[470],{"type":49,"tag":94,"props":471,"children":472},{},[473],{"type":55,"value":474},"class Team(SQLModel, table=True):\n",{"type":49,"tag":94,"props":476,"children":477},{"class":96,"line":189},[478],{"type":49,"tag":94,"props":479,"children":480},{},[481],{"type":55,"value":195},{"type":49,"tag":94,"props":483,"children":484},{"class":96,"line":198},[485],{"type":49,"tag":94,"props":486,"children":487},{},[488],{"type":55,"value":489},"    heroes: list[\"Hero\"] = Relationship(back_populates=\"team\")\n",{"type":49,"tag":94,"props":491,"children":492},{"class":96,"line":207},[493],{"type":49,"tag":94,"props":494,"children":496},{"emptyLinePlaceholder":495},true,[497],{"type":55,"value":498},"\n",{"type":49,"tag":94,"props":500,"children":502},{"class":96,"line":501},5,[503],{"type":49,"tag":94,"props":504,"children":505},{"emptyLinePlaceholder":495},[506],{"type":55,"value":498},{"type":49,"tag":94,"props":508,"children":510},{"class":96,"line":509},6,[511],{"type":49,"tag":94,"props":512,"children":513},{},[514],{"type":55,"value":186},{"type":49,"tag":94,"props":516,"children":518},{"class":96,"line":517},7,[519],{"type":49,"tag":94,"props":520,"children":521},{},[522],{"type":55,"value":195},{"type":49,"tag":94,"props":524,"children":526},{"class":96,"line":525},8,[527],{"type":49,"tag":94,"props":528,"children":529},{},[530],{"type":55,"value":213},{"type":49,"tag":94,"props":532,"children":534},{"class":96,"line":533},9,[535],{"type":49,"tag":94,"props":536,"children":537},{},[538],{"type":55,"value":539},"    team: Team | None = Relationship(back_populates=\"heroes\")\n",{"type":49,"tag":58,"props":541,"children":542},{},[543],{"type":55,"value":544},"Many-to-many:",{"type":49,"tag":84,"props":546,"children":548},{"className":86,"code":547,"language":23,"meta":88,"style":88},"class 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",[549],{"type":49,"tag":76,"props":550,"children":551},{"__ignoreMap":88},[552,560,568,576,583,590,597,604,612,619,627,635,643],{"type":49,"tag":94,"props":553,"children":554},{"class":96,"line":97},[555],{"type":49,"tag":94,"props":556,"children":557},{},[558],{"type":55,"value":559},"class HeroTeamLink(SQLModel, table=True):\n",{"type":49,"tag":94,"props":561,"children":562},{"class":96,"line":189},[563],{"type":49,"tag":94,"props":564,"children":565},{},[566],{"type":55,"value":567},"    team_id: int | None = Field(default=None, foreign_key=\"team.id\", primary_key=True)\n",{"type":49,"tag":94,"props":569,"children":570},{"class":96,"line":198},[571],{"type":49,"tag":94,"props":572,"children":573},{},[574],{"type":55,"value":575},"    hero_id: int | None = Field(default=None, foreign_key=\"hero.id\", primary_key=True)\n",{"type":49,"tag":94,"props":577,"children":578},{"class":96,"line":207},[579],{"type":49,"tag":94,"props":580,"children":581},{"emptyLinePlaceholder":495},[582],{"type":55,"value":498},{"type":49,"tag":94,"props":584,"children":585},{"class":96,"line":501},[586],{"type":49,"tag":94,"props":587,"children":588},{"emptyLinePlaceholder":495},[589],{"type":55,"value":498},{"type":49,"tag":94,"props":591,"children":592},{"class":96,"line":509},[593],{"type":49,"tag":94,"props":594,"children":595},{},[596],{"type":55,"value":474},{"type":49,"tag":94,"props":598,"children":599},{"class":96,"line":517},[600],{"type":49,"tag":94,"props":601,"children":602},{},[603],{"type":55,"value":195},{"type":49,"tag":94,"props":605,"children":606},{"class":96,"line":525},[607],{"type":49,"tag":94,"props":608,"children":609},{},[610],{"type":55,"value":611},"    heroes: list[\"Hero\"] = Relationship(back_populates=\"teams\", link_model=HeroTeamLink)\n",{"type":49,"tag":94,"props":613,"children":614},{"class":96,"line":533},[615],{"type":49,"tag":94,"props":616,"children":617},{"emptyLinePlaceholder":495},[618],{"type":55,"value":498},{"type":49,"tag":94,"props":620,"children":622},{"class":96,"line":621},10,[623],{"type":49,"tag":94,"props":624,"children":625},{"emptyLinePlaceholder":495},[626],{"type":55,"value":498},{"type":49,"tag":94,"props":628,"children":630},{"class":96,"line":629},11,[631],{"type":49,"tag":94,"props":632,"children":633},{},[634],{"type":55,"value":186},{"type":49,"tag":94,"props":636,"children":638},{"class":96,"line":637},12,[639],{"type":49,"tag":94,"props":640,"children":641},{},[642],{"type":55,"value":195},{"type":49,"tag":94,"props":644,"children":646},{"class":96,"line":645},13,[647],{"type":49,"tag":94,"props":648,"children":649},{},[650],{"type":55,"value":651},"    teams: list[Team] = Relationship(back_populates=\"heroes\", link_model=HeroTeamLink)\n",{"type":49,"tag":58,"props":653,"children":654},{},[655],{"type":55,"value":656},"If 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.",{"type":49,"tag":58,"props":658,"children":659},{},[660,662,668],{"type":55,"value":661},"When 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":49,"tag":76,"props":663,"children":665},{"className":664},[],[666],{"type":55,"value":667},"TYPE_CHECKING",{"type":55,"value":669}," imports plus string annotations:",{"type":49,"tag":84,"props":671,"children":673},{"className":86,"code":672,"language":23,"meta":88,"style":88},"if TYPE_CHECKING:\n    from .team_model import Team\n\nteam: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n",[674],{"type":49,"tag":76,"props":675,"children":676},{"__ignoreMap":88},[677,685,693,700],{"type":49,"tag":94,"props":678,"children":679},{"class":96,"line":97},[680],{"type":49,"tag":94,"props":681,"children":682},{},[683],{"type":55,"value":684},"if TYPE_CHECKING:\n",{"type":49,"tag":94,"props":686,"children":687},{"class":96,"line":189},[688],{"type":49,"tag":94,"props":689,"children":690},{},[691],{"type":55,"value":692},"    from .team_model import Team\n",{"type":49,"tag":94,"props":694,"children":695},{"class":96,"line":198},[696],{"type":49,"tag":94,"props":697,"children":698},{"emptyLinePlaceholder":495},[699],{"type":55,"value":498},{"type":49,"tag":94,"props":701,"children":702},{"class":96,"line":207},[703],{"type":49,"tag":94,"props":704,"children":705},{},[706],{"type":55,"value":707},"team: Optional[\"Team\"] = Relationship(back_populates=\"heroes\")\n",{"type":49,"tag":58,"props":709,"children":710},{},[711,713,719,721,727,729,735],{"type":55,"value":712},"For SQLAlchemy relationship options not exposed as first-class SQLModel parameters, prefer ",{"type":49,"tag":76,"props":714,"children":716},{"className":715},[],[717],{"type":55,"value":718},"Relationship(sa_relationship_kwargs={...})",{"type":55,"value":720}," or ",{"type":49,"tag":76,"props":722,"children":724},{"className":723},[],[725],{"type":55,"value":726},"Relationship(sa_relationship_args=[...])",{"type":55,"value":728},". Use ",{"type":49,"tag":76,"props":730,"children":732},{"className":731},[],[733],{"type":55,"value":734},"sa_relationship=relationship(...)",{"type":55,"value":736}," only as an escape hatch when SQLModel's relationship wrapper cannot express the mapping.",{"type":49,"tag":64,"props":738,"children":740},{"id":739},"creates-and-updates",[741],{"type":55,"value":742},"Creates and Updates",{"type":49,"tag":58,"props":744,"children":745},{},[746],{"type":55,"value":747},"Use direct construction for trusted internal values:",{"type":49,"tag":84,"props":749,"children":751},{"className":86,"code":750,"language":23,"meta":88,"style":88},"hero = Hero(name=\"Deadpond\", secret_name=\"Dive Wilson\")\n",[752],{"type":49,"tag":76,"props":753,"children":754},{"__ignoreMap":88},[755],{"type":49,"tag":94,"props":756,"children":757},{"class":96,"line":97},[758],{"type":49,"tag":94,"props":759,"children":760},{},[761],{"type":55,"value":750},{"type":49,"tag":58,"props":763,"children":764},{},[765,767,773],{"type":55,"value":766},"Build table objects from data models with ",{"type":49,"tag":76,"props":768,"children":770},{"className":769},[],[771],{"type":55,"value":772},"Model.model_validate(...)",{"type":55,"value":82},{"type":49,"tag":84,"props":775,"children":777},{"className":86,"code":776,"language":23,"meta":88,"style":88},"db_hero = Hero.model_validate(hero_create)\n",[778],{"type":49,"tag":76,"props":779,"children":780},{"__ignoreMap":88},[781],{"type":49,"tag":94,"props":782,"children":783},{"class":96,"line":97},[784],{"type":49,"tag":94,"props":785,"children":786},{},[787],{"type":55,"value":776},{"type":49,"tag":58,"props":789,"children":790},{},[791,793,799,801,807,809,815,817,823,825,831,833,839],{"type":55,"value":792},"For FastAPI, use a split model pattern: ",{"type":49,"tag":76,"props":794,"children":796},{"className":795},[],[797],{"type":55,"value":798},"HeroBase",{"type":55,"value":800}," for shared fields, ",{"type":49,"tag":76,"props":802,"children":804},{"className":803},[],[805],{"type":55,"value":806},"Hero(HeroBase, table=True)",{"type":55,"value":808}," for the table, ",{"type":49,"tag":76,"props":810,"children":812},{"className":811},[],[813],{"type":55,"value":814},"HeroCreate",{"type":55,"value":816}," for input, ",{"type":49,"tag":76,"props":818,"children":820},{"className":819},[],[821],{"type":55,"value":822},"HeroUpdate",{"type":55,"value":824}," with all-optional fields for PATCH, ",{"type":49,"tag":76,"props":826,"children":828},{"className":827},[],[829],{"type":55,"value":830},"HeroPublic",{"type":55,"value":832}," for output, and relationship-specific public models such as ",{"type":49,"tag":76,"props":834,"children":836},{"className":835},[],[837],{"type":55,"value":838},"HeroPublicWithTeam",{"type":55,"value":840}," only where needed.",{"type":49,"tag":58,"props":842,"children":843},{},[844],{"type":55,"value":845},"For partial updates, dump only provided fields and update in place:",{"type":49,"tag":84,"props":847,"children":849},{"className":86,"code":848,"language":23,"meta":88,"style":88},"hero_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",[850],{"type":49,"tag":76,"props":851,"children":852},{"__ignoreMap":88},[853,861,869,877,884],{"type":49,"tag":94,"props":854,"children":855},{"class":96,"line":97},[856],{"type":49,"tag":94,"props":857,"children":858},{},[859],{"type":55,"value":860},"hero_data = hero_update.model_dump(exclude_unset=True)\n",{"type":49,"tag":94,"props":862,"children":863},{"class":96,"line":189},[864],{"type":49,"tag":94,"props":865,"children":866},{},[867],{"type":55,"value":868},"db_hero.sqlmodel_update(hero_data)\n",{"type":49,"tag":94,"props":870,"children":871},{"class":96,"line":198},[872],{"type":49,"tag":94,"props":873,"children":874},{},[875],{"type":55,"value":876},"session.add(db_hero)\n",{"type":49,"tag":94,"props":878,"children":879},{"class":96,"line":207},[880],{"type":49,"tag":94,"props":881,"children":882},{},[883],{"type":55,"value":427},{"type":49,"tag":94,"props":885,"children":886},{"class":96,"line":501},[887],{"type":49,"tag":94,"props":888,"children":889},{},[890],{"type":55,"value":891},"session.refresh(db_hero)\n",{"type":49,"tag":64,"props":893,"children":895},{"id":894},"metadata-and-app-setup",[896],{"type":55,"value":897},"Metadata and App Setup",{"type":49,"tag":58,"props":899,"children":900},{},[901,903,909,911,917],{"type":55,"value":902},"Call ",{"type":49,"tag":76,"props":904,"children":906},{"className":905},[],[907],{"type":55,"value":908},"SQLModel.metadata.create_all(engine)",{"type":55,"value":910}," only after all table model classes have been imported. In FastAPI examples, use a dependency that yields ",{"type":49,"tag":76,"props":912,"children":914},{"className":913},[],[915],{"type":55,"value":916},"Session(engine)",{"type":55,"value":454},{"type":49,"tag":58,"props":919,"children":920},{},[921],{"type":55,"value":922},"For tests and small examples, SQLite is a common option; when using it, create metadata explicitly and use direct sessions:",{"type":49,"tag":84,"props":924,"children":926},{"className":86,"code":925,"language":23,"meta":88,"style":88},"engine = create_engine(\"sqlite:\u002F\u002F\u002F:memory:\")\nSQLModel.metadata.create_all(engine)\nwith Session(engine) as session:\n    ...\n",[927],{"type":49,"tag":76,"props":928,"children":929},{"__ignoreMap":88},[930,938,946,953],{"type":49,"tag":94,"props":931,"children":932},{"class":96,"line":97},[933],{"type":49,"tag":94,"props":934,"children":935},{},[936],{"type":55,"value":937},"engine = create_engine(\"sqlite:\u002F\u002F\u002F:memory:\")\n",{"type":49,"tag":94,"props":939,"children":940},{"class":96,"line":189},[941],{"type":49,"tag":94,"props":942,"children":943},{},[944],{"type":55,"value":945},"SQLModel.metadata.create_all(engine)\n",{"type":49,"tag":94,"props":947,"children":948},{"class":96,"line":198},[949],{"type":49,"tag":94,"props":950,"children":951},{},[952],{"type":55,"value":278},{"type":49,"tag":94,"props":954,"children":955},{"class":96,"line":207},[956],{"type":49,"tag":94,"props":957,"children":958},{},[959],{"type":55,"value":960},"    ...\n",{"type":49,"tag":58,"props":962,"children":963},{},[964],{"type":55,"value":965},"When using SQLite with FastAPI, include:",{"type":49,"tag":84,"props":967,"children":969},{"className":86,"code":968,"language":23,"meta":88,"style":88},"connect_args = {\"check_same_thread\": False}\nengine = create_engine(sqlite_url, connect_args=connect_args)\n",[970],{"type":49,"tag":76,"props":971,"children":972},{"__ignoreMap":88},[973,981],{"type":49,"tag":94,"props":974,"children":975},{"class":96,"line":97},[976],{"type":49,"tag":94,"props":977,"children":978},{},[979],{"type":55,"value":980},"connect_args = {\"check_same_thread\": False}\n",{"type":49,"tag":94,"props":982,"children":983},{"class":96,"line":189},[984],{"type":49,"tag":94,"props":985,"children":986},{},[987],{"type":55,"value":988},"engine = create_engine(sqlite_url, connect_args=connect_args)\n",{"type":49,"tag":64,"props":990,"children":992},{"id":991},"deletes",[993],{"type":55,"value":994},"Deletes",{"type":49,"tag":58,"props":996,"children":997},{},[998],{"type":55,"value":999},"Use SQLModel's relationship helpers for cascades:",{"type":49,"tag":84,"props":1001,"children":1003},{"className":86,"code":1002,"language":23,"meta":88,"style":88},"heroes: list[\"Hero\"] = Relationship(back_populates=\"team\", cascade_delete=True)\nteam_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"CASCADE\")\n",[1004],{"type":49,"tag":76,"props":1005,"children":1006},{"__ignoreMap":88},[1007,1015],{"type":49,"tag":94,"props":1008,"children":1009},{"class":96,"line":97},[1010],{"type":49,"tag":94,"props":1011,"children":1012},{},[1013],{"type":55,"value":1014},"heroes: list[\"Hero\"] = Relationship(back_populates=\"team\", cascade_delete=True)\n",{"type":49,"tag":94,"props":1016,"children":1017},{"class":96,"line":189},[1018],{"type":49,"tag":94,"props":1019,"children":1020},{},[1021],{"type":55,"value":1022},"team_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"CASCADE\")\n",{"type":49,"tag":58,"props":1024,"children":1025},{},[1026,1028,1034,1036,1042,1044,1050],{"type":55,"value":1027},"For database-level delete behavior such as ",{"type":49,"tag":76,"props":1029,"children":1031},{"className":1030},[],[1032],{"type":55,"value":1033},"SET NULL",{"type":55,"value":1035},", pair ",{"type":49,"tag":76,"props":1037,"children":1039},{"className":1038},[],[1040],{"type":55,"value":1041},"ondelete",{"type":55,"value":1043}," with a nullable foreign key and use ",{"type":49,"tag":76,"props":1045,"children":1047},{"className":1046},[],[1048],{"type":55,"value":1049},"passive_deletes",{"type":55,"value":1051}," on the relationship when appropriate.",{"type":49,"tag":58,"props":1053,"children":1054},{},[1055,1061],{"type":49,"tag":76,"props":1056,"children":1058},{"className":1057},[],[1059],{"type":55,"value":1060},"ondelete=\"SET NULL\"",{"type":55,"value":1062}," requires a nullable foreign key:",{"type":49,"tag":84,"props":1064,"children":1066},{"className":86,"code":1065,"language":23,"meta":88,"style":88},"team_id: int | None = Field(default=None, foreign_key=\"team.id\", ondelete=\"SET NULL\")\n",[1067],{"type":49,"tag":76,"props":1068,"children":1069},{"__ignoreMap":88},[1070],{"type":49,"tag":94,"props":1071,"children":1072},{"class":96,"line":97},[1073],{"type":49,"tag":94,"props":1074,"children":1075},{},[1076],{"type":55,"value":1065},{"type":49,"tag":64,"props":1078,"children":1080},{"id":1079},"sqlalchemy-escape-hatches",[1081],{"type":55,"value":1082},"SQLAlchemy Escape Hatches",{"type":49,"tag":58,"props":1084,"children":1085},{},[1086,1088,1094,1095,1101,1102,1108,1109,1115,1117,1122],{"type":55,"value":1087},"Use SQLModel's ",{"type":49,"tag":76,"props":1089,"children":1091},{"className":1090},[],[1092],{"type":55,"value":1093},"Field(sa_type=...)",{"type":55,"value":115},{"type":49,"tag":76,"props":1096,"children":1098},{"className":1097},[],[1099],{"type":55,"value":1100},"Field(sa_column=...)",{"type":55,"value":115},{"type":49,"tag":76,"props":1103,"children":1105},{"className":1104},[],[1106],{"type":55,"value":1107},"Field(sa_column_args=...)",{"type":55,"value":137},{"type":49,"tag":76,"props":1110,"children":1112},{"className":1111},[],[1113],{"type":55,"value":1114},"Field(sa_column_kwargs=...)",{"type":55,"value":1116}," only when normal ",{"type":49,"tag":76,"props":1118,"children":1120},{"className":1119},[],[1121],{"type":55,"value":170},{"type":55,"value":1123}," parameters do not cover a column or type requirement. Do not switch the whole model to SQLAlchemy declarative style for one custom column.",{"type":49,"tag":1125,"props":1126,"children":1127},"style",{},[1128],{"type":55,"value":1129},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1131,"total":97},[1132],{"slug":4,"name":4,"fn":5,"description":6,"org":1133,"tags":1134,"stars":28,"repoUrl":29,"updatedAt":30},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1135,1136,1137,1138,1139,1140],{"name":16,"slug":17,"type":14},{"name":9,"slug":8,"type":14},{"name":19,"slug":20,"type":14},{"name":22,"slug":23,"type":14},{"name":25,"slug":26,"type":14},{"name":13,"slug":4,"type":14},{"items":1142,"total":189},[1143,1160],{"slug":8,"name":8,"fn":1144,"description":1145,"org":1146,"tags":1147,"stars":1157,"repoUrl":1158,"updatedAt":1159},"implement FastAPI best practices","FastAPI best practices and conventions. Use when working with FastAPI APIs, Pydantic models, dependencies, streaming responses including Server-Sent Events (SSE), and serving frontend apps. Keeps FastAPI code clean and up to date with the latest features and patterns.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1148,1151,1154,1155],{"name":1149,"slug":1150,"type":14},"API Development","api-development",{"name":1152,"slug":1153,"type":14},"Backend","backend",{"name":9,"slug":8,"type":14},{"name":1156,"slug":36,"type":14},"Pydantic",101582,"https:\u002F\u002Fgithub.com\u002Ffastapi\u002Ffastapi","2026-09-01T08:30:37.275731",{"slug":4,"name":4,"fn":5,"description":6,"org":1161,"tags":1162,"stars":28,"repoUrl":29,"updatedAt":30},{"slug":8,"name":9,"logoUrl":10,"githubOrg":8},[1163,1164,1165,1166,1167,1168],{"name":16,"slug":17,"type":14},{"name":9,"slug":8,"type":14},{"name":19,"slug":20,"type":14},{"name":22,"slug":23,"type":14},{"name":25,"slug":26,"type":14},{"name":13,"slug":4,"type":14}]