Код: Выделить всё
...
│ ├── modules
│ │ ├── box
│ │ │ ├── routes.py
│ │ │ ├── services.py
│ │ │ ├── models.py # the sqlalchemy classes
│ │ │ ├── schemas.py # the pydantic schemas
│ │ ├── toy
│ │ │ ├── routes.py
│ │ │ ├── services.py
│ │ │ ├── models.py
│ │ │ ├── schemas.py
В этом примере я использую два модуля, которые представляют коробки и игрушки. Каждая игрушка хранится в одной коробке, а каждая коробка содержит несколько игрушек в соответствии с классическим соотношением 1 x N.
С SQLAlchemy все работает хорошо , определить отношения очень просто, используя TYPE_CHECKING для обработки циклических зависимостей:
Код: Выделить всё
# my_app.modules.box.models.py
from sqlalchemy.orm import Mapped, mapped_column, relationship
if TYPE_CHECKING:
from my_app.modules.toy.models import Toy
class Box(Base):
__tablename__ = "box"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
toys: Mapped[list["Toy"]] = relationship(back_populates="box")
Код: Выделить всё
# my_app.modules.toy.models.py
from sqlalchemy.orm import Mapped, mapped_column, relationship
if TYPE_CHECKING:
from my_app.modules.box.models import Box
class Toy(Base):
__tablename__ = "toy"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
box: Mapped["Box"] = relationship(back_populates="toys")
Код: Выделить всё
# my_app.modules.box.schemas.py
from my_app.modules.toy.schemas import ToyResponse
class BoxResponse(BaseModel):
id: int
toys: list[ToyResponse]
Код: Выделить всё
# my_app.modules.toy.schemas.py
from my_app.modules.box.schemas import BoxResponse
class ToyResponse(BaseModel):
id: int
box: BoxResponse
Код: Выделить всё
ImportError: cannot import name 'Toy' from partially initialized module 'my_app.modules.toy.schemas' (most likely due to a circular import)...
Код: Выделить всё
# my_app.modules.box.schemas.py
if TYPE_CHECKING:
from my_app.modules.toy.schemas import ToyResponse
class BoxResponse(BaseModel):
id: int
toys: list["ToyResponse"]
Код: Выделить всё
# my_app.modules.toy.schemas.py
if TYPE_CHECKING:
from my_app.modules.box.schemas import BoxResponse
class ToyResponse(BaseModel):
id: int
box: "BoxResponse"
Код: Выделить всё
raise PydanticUndefinedAnnotation.from_name_error(e) from e
pydantic.errors.PydanticUndefinedAnnotation: name 'Toy' is not defined
Возможно, я ошибаюсь, но я считаю связь между Box и Toy чем-то тривиальным и фундаментальным. это должно быть осуществимо в любом умеренно сложном проекте. Например, простым вариантом использования может быть запрос игрушки вместе с коробкой, в которой она находится, и наоборот, коробкой со всеми игрушками. Разве это не законные запросы?
Итак, мой вопрос
Как я могу определить взаимосвязанные схемы Pydantic (
Код: Выделить всё
BoxResponse
Подробнее здесь: https://stackoverflow.com/questions/790 ... th-fastapi