Обработка циклического импорта в моделях Pydantic с помощью FastAPIPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Обработка циклического импорта в моделях Pydantic с помощью FastAPI

Сообщение Anonymous »

Я разрабатываю приложение FastAPI, имеющее следующую структуру модулей.

Код: Выделить всё

...
│   ├── 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
Каждый модуль содержит модели SQLAlchemy, модели Pydantic (также называемые схемами), маршруты FastAPI и службы, обрабатывающие бизнес-логику.
В этом примере я использую два модуля, которые представляют коробки и игрушки. Каждая игрушка хранится в одной коробке, а каждая коробка содержит несколько игрушек в соответствии с классическим соотношением 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")

Эта настройка работает идеально, не вызывая ошибок циклического импорта. Однако я сталкиваюсь с проблемами при определении одинаковых отношений между схемами Pydantic. Если я напрямую импортирую модули в свой файл Schemas.py,

Код: Выделить всё

# 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)...
Я также пробую подход SQLAlchemy TYPE_CHECKING и объявление строки:

Код: Выделить всё

# 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"
Но, видимо, pydantic это не поддерживает:

Код: Выделить всё

raise PydanticUndefinedAnnotation.from_name_error(e) from e
pydantic.errors.PydanticUndefinedAnnotation: name 'Toy' is not defined
(Некоторые ответы) предполагают, что проблема связана с плохой организацией модуля. (Другие) предлагают слишком сложные и трудные для понимания решения.
Возможно, я ошибаюсь, но я считаю связь между Box и Toy чем-то тривиальным и фундаментальным. это должно быть осуществимо в любом умеренно сложном проекте. Например, простым вариантом использования может быть запрос игрушки вместе с коробкой, в которой она находится, и наоборот, коробкой со всеми игрушками. Разве это не законные запросы?
Итак, мой вопрос
Как я могу определить взаимосвязанные схемы Pydantic (

Код: Выделить всё

BoxResponse
и ToyResponse), которые ссылаются друг на друга, не встречая циклических ошибок импорта? Я ищу четкое и удобное в сопровождении решение, сохраняющее независимость коробочных и игрушечных модулей, аналогично тому, как отношения обрабатываются в моделях SQLAlchemy. Есть какие-нибудь предложения или хотя бы объяснение, почему этого так сложно достичь?

Подробнее здесь: https://stackoverflow.com/questions/790 ... th-fastapi
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Обработка циклического импорта в моделях Pydantic с помощью FastAPI
    Anonymous » » в форуме Python
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous
  • Что происходит при использовании взаимного или циклического (циклического) импорта?
    Anonymous » » в форуме Python
    0 Ответы
    20 Просмотры
    Последнее сообщение Anonymous
  • Проблема циклического импорта с моделями FastAPI и Pydantic
    Anonymous » » в форуме Python
    0 Ответы
    39 Просмотры
    Последнее сообщение Anonymous
  • Проблема циклического импорта с моделями FastAPI и Pydantic
    Anonymous » » в форуме Python
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous
  • Проблема циклического импорта с моделями FastAPI и Pydantic
    Anonymous » » в форуме Python
    0 Ответы
    17 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»