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 sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship

from examples.api_for_sqlalchemy.extensions.sqlalchemy import Base
from examples.api_for_sqlalchemy.utils.sqlalchemy.base_model_mixin import BaseModelMixin


class User(Base, BaseModelMixin):
    __tablename__ = "users"
    id = Column(Integer, primary_key=True, autoincrement=True)
    name: str = Column(String)

    posts = relationship("Post", back_populates="user", uselist=True)
    bio = relationship("UserBio", back_populates="user", uselist=False)
    computers = relationship("Computer", back_populates="user", uselist=True)


class Computer(Base, BaseModelMixin):
    __tablename__ = "computers"

    id = Column(Integer, primary_key=True, autoincrement=True)
    name = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey("users.id"), nullable=True)
    user = relationship("User", back_populates="computers")


class UserBio(Base, BaseModelMixin):
    __tablename__ = "user_bio"
    id = Column(Integer, primary_key=True, autoincrement=True)
    birth_city: str = Column(String, nullable=False, default="", server_default="")
    favourite_movies: str = Column(String, nullable=False, default="", server_default="")
    user_id = Column(Integer, ForeignKey("users.id"), nullable=False, unique=True)
    user = relationship("User", back_populates="bio", uselist=False)

Schemas:

from typing import Optional

from pydantic import BaseModel as PydanticBaseModel

from fastapi_jsonapi.schema_base import Field, RelationshipInfo


class BaseModel(PydanticBaseModel):
    class Config:
        orm_mode = True


class UserBaseSchema(BaseModel):
    id: int
    name: str
    bio: Optional["UserBioSchema"] = Field(
        relationship=RelationshipInfo(
            resource_type="user_bio",
        ),
    )
    computers: Optional["ComputerSchema"] = Field(
        relationship=RelationshipInfo(
            resource_type="computer",
            many=True,
        ),
    )


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


class UserBioBaseSchema(BaseModel):
    birth_city: str
    favourite_movies: str
    keys_to_ids_list: dict[str, list[int]] = None

    user: "UserSchema" = Field(
        relationship=RelationshipInfo(
            resource_type="user",
        ),
    )


class ComputerBaseSchema(BaseModel):
    id: int
    name: str
    user: Optional["UserSchema"] = Field(
        relationship=RelationshipInfo(
            resource_type="user",
        ),
    )