I'm trying to leverage SQLModel "Relationships" in a FastAPI app. Specifically, I want to break my model classes out into separate files. I found the official SQLModel documentation describing how to deal with circular dependencies which describes how to use TYPE_CHECKING to sort of bypass the typing issues; and by itself, that allows the API to build. The problem arises when I try to declare a response_model on my API endpoint with one of the classes from one of those files. The API request raises: pydantic.errors.PydanticUserError: TypeAdapter[typing.Annotated[team.TeamResponse, FieldInfo(annotation=TeamResponse, required=True)]] is not fully defined; you should define typing.Annotated[team.TeamResponse, FieldInfo(annotation=TeamResponse, required=True)] and all referenced types, then call .rebuild() on the instance. And I think that makes sense that I'm getting an error (although the particular error is cryptic); after all, I used the TYPE_CHECKING voodoo on the model classes, but now I'm explicitly referencing TeamResponse, and expecting to get all the type information for the API request. So assuming I do NOT want to store all my models in one big class, how can I deal with circular dependencies in model classes AND specify a response_model with related data being returned? hero.py from typing import TYPE_CHECKING from sqlmodel import SQLModel, Field, Relationship if TYPE_CHECKING: from .team import Team class Hero(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str team_id: int | None = Field(default=None, foreign_key="team.id") team: "Team" = Relationship(back_populates="heroes") class HeroResponse(BaseModel): name: str team: "Team" team.py from typing import TYPE_CHECKING from pydantic import BaseModel from sqlmodel import SQLModel, Field, Relationship if TYPE_CHECKING: from .hero import Hero, HeroResponse class Team(SQLModel, table=True): id: int | None = Field(default=None, primary_key=True) name: str heroes: list["Hero"] = Relationship(back_populates="team") class TeamResponse(BaseModel): """What I want returned from the API""" name: str heroes: list["HeroResponse"] app.py from fastapi import FastAPI, Depends from sqlmodel import Session, create_engine, select, SQLModel from team import TeamResponse, Team from hero import Hero engine = create_engine("sqlite:///db.db") app = FastAPI() async def get_session(): session = Session(engine) try: yield session finally: session.close() @app.get("/teams", response_model=list[TeamResponse]) def get_teams(session = Depends(get_session)): stmt = select(Team) heroes = session.exec(stmt).all() return heroes # If you want to stage some data if __name__ == "__main__": SQLModel.metadata.create_all(engine) preservers = Team(name="Preservers") hero1 = Hero(name="The Flash", team=preservers) hero2 = Hero(name="Superman", team=preservers) with Session(engine) as session: session.add_all([preservers,hero1, hero2]) session.refresh(preservers) session.refresh(hero1) session.refresh(hero2) session.commit() Continue reading...