I'm building an API with FastAPI and SQLModel, but I'm having trouble getting nested relationships to show up in my API responses. I've set up eager loading with selectinload, but the nested data isn't appearing in the output.
Here's my main Contact model:
class Contact(SQLModel, table=True):
id: Optional[int] = Field(default=None, primary_key=True)
user_id: str = Field(foreign_key="user.id")
user: User = Relationship(back_populates="contacts")
fn: str
nickname: Optional[str] = None
org: Optional[str] = None
title: Optional[str] = None
birthday: Optional[int] = None
note: Optional[str] = None
name: Name = Relationship(back_populates="contact")
emails: List[Email] = Relationship(back_populates="contact")
phones: List[Phone] = Relationship(back_populates="contact")
addresses: List[Address] = Relationship(back_populates="contact")
socials: List[Social] = Relationship(back_populates="contact")
websites: List[Website] = Relationship(back_populates="contact")
class Config:
populate_by_name = True
And here's my FastAPI route
@router.get("/", response_model=List[Contact])
def get_contacts(token: Token, session: Session = Depends(get_session)):
query = (
select(Contact)
.options(
selectinload(Contact.name),
selectinload(Contact.emails),
selectinload(Contact.phones),
selectinload(Contact.addresses),
selectinload(Contact.socials),
selectinload(Contact.websites),
)
.join(User)
.where(User.id == token.sub)
.order_by(Contact.id)
)
contacts = session.exec(query).all()
if not contacts:
raise HTTPException(status_code=404, detail="No contacts found for this user")
return contacts
However, the API response doesn't include any of the nested relationships (name, emails, phones, etc.)