Serialize relationship in SQLModel

194 Views Asked by At

Lets say I have 2 models in relationship and an endpoint in sqlmodel and fastapi:

class Search(SQLModel, table=True):
    id: int = Field(default=None, nullable=True, primary_key=True, index=True)
    videos: list["Video"] = Relationship(back_populates="search")


class Video(SQLModel, table=True):
    id: int = Field(default=None, nullable=True, primary_key=True, index=True)
    search_id: int = Field(foreign_key="search.id")
    search: "Search" = Relationship(back_populates="videos")

@router.get("/", response_model=Video)
def read_videos(
        db: Session = Depends(deps.get_db),
    ):
    return db.query(Video).first()

This works fine, but does not return nested dictonary with search relationship. If I simply create

class VideoResponse(SQLModel):
    id: int
    search_id: int
    search: Search

and change response_model to VideoResponse, everything works as I wish. However it brings some redundancy which in fact SQLModel aims to remove. Is it possible to solve this in some clean way? Would it be possible to make SQLModel serialize relationship by default?

1

There are 1 best solutions below

3
On

According to the SQLModel's documentation you can reduce redundancy like shown below:

class SearchBase(SQLModel):
    id: int = Field(default=None, nullable=True, primary_key=True, index=True)

class Search(SearchBase, table=True):
    videos: list["Video"] = Relationship(back_populates="search")

class VideoBase(SQLModel):
    id: int = Field(default=None, nullable=True, primary_key=True, index=True)
    search_id: int = Field(foreign_key="search.id")

class Video(VideoBase, table=True):
    search: "Search" = Relationship(back_populates="videos")

class VideoResponse(VideoBase):
    search: SearchBase

@router.get("/", response_model=VideoResponse)
def read_videos(
        db: Session = Depends(deps.get_db),
    ):
    return db.query(Video).first()

You can't get rid of all the redundancy because if you use models with relationship as an output model it might cause an infinite loop.