Define relationships

As noted in quickstart, objects can accept a relationships. In order to make it technically possible to create, update, and modify relationships, you must declare a RelationShipInfo when creating a schema.

As an example, let’s say you have a user model, their biography, and the computers they own. The user and biographies are connected by To-One relationship, the user and computers are connected by To-Many relationship

Models:

from __future__ import annotations

from typing import Optional

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship, Mapped, mapped_column

from examples.api_for_sqlalchemy.models.base import Base


class User(Base):
    __tablename__ = "users"

    name: Mapped[str]

    bio: Mapped[UserBio] = relationship(back_populates="user")
    computers: Mapped[list[Computer]] = relationship(back_populates="user")


class Computer(Base):
    __tablename__ = "computers"

    name: Mapped[str]

    user_id: Mapped[Optional[int]] = mapped_column(ForeignKey("users.id"))
    user: Mapped[User] = relationship(back_populates="computers")


class UserBio(Base):
    __tablename__ = "user_bio"

    birth_city: Mapped[str] = mapped_column(default="", server_default="")
    favourite_movies: Mapped[str] = mapped_column(default="", server_default="")

    user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), unique=True)
    user: Mapped[User] = relationship(back_populates="bio")

Schemas:

from __future__ import annotations

from typing import Optional, Annotated

from pydantic import BaseModel, ConfigDict

from fastapi_jsonapi.types_metadata import RelationshipInfo


class UserBaseSchema(BaseModel):
    model_config = ConfigDict(
        from_attributes=True,
    )

    id: int
    name: str

    bio: Annotated[
        Optional[UserBioBaseSchema],
        RelationshipInfo(
            resource_type="user_bio",
        ),
    ] = None
    computers: Annotated[
        Optional[list[ComputerBaseSchema]],
        RelationshipInfo(
            resource_type="computer",
            many=True,
        ),
    ] = None


class UserSchema(BaseModel):
    id: int
    name: str


class UserBioBaseSchema(BaseModel):
    birth_city: str
    favourite_movies: str

    user: Annotated[
        Optional[UserSchema],
        RelationshipInfo(
            resource_type="user",
        ),
    ] = None


class ComputerBaseSchema(BaseModel):
    id: int
    name: str

    user: Annotated[
        Optional[UserSchema],
        RelationshipInfo(
            resource_type="user",
        ),
    ] = None