在FastAPI中避免循环导入
我正在学习FastAPI,并计划把应用按如下结构组织:
app in FastAPI:
- models.py文件,用于存放数据库以及其他重要的Python相关方法
- routes.py文件,用于放置路由(URL)
- schemas.py文件,用于按路由需要存放不同的数据模式
现在我创建了一个名为users的应用及其模型,如下所示
class User(Base):
__tablename__ = "users"
id: Mapped[int | None] = mapped_column(Integer, primary_key=True, default=None) # autoincrement=True
username: Mapped[str] = mapped_column(String(50), unique=True, nullable=False)
email: Mapped[str] = mapped_column(String(120), unique=True, nullable=False)
hashed_password: Mapped[str] = mapped_column(String(200), nullable=False)
profile: Mapped[Profile] = relationship("Profile", back_populates="user", uselist=False)
class Profile(Base):
__tablename__ = "profiles"
id: Mapped[int | None] = mapped_column(Integer, primary_key=True, default=None)
user: Mapped[User] = relationship("User", back_populates="profile")
user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), nullable=False, index=True)
paied_until: Mapped[datetime] = mapped_column(
DateTime(timezone=True), default=lambda: datetime.now(timezone.utc), nullable=False
)
from_phone: Mapped[str | None] = mapped_column(String(20), nullable=True, default=None)
messages: Mapped[list[WAMessage]] = relationship(back_populates="profile", cascade="all, delete-orphan")
注意,这里我与WAMessage之间存在关联,由于Mapped的原因,我必须把该类加入其中。
现在在另一个文件夹中的WAMessage.models,我添加了如下代码
class WAMessage(Base):
__tablename__ = 'wa_messages'
status: Mapped[str] = mapped_column(String(9), nullable=False, default=WAMessageStatusChoices.waiting)
attachment_file: Mapped[str | None] = mapped_column(String(200), nullable=True, default=None)
content: Mapped[str] = mapped_column(Text, nullable=False)
user_id: Mapped[str] = mapped_column(ForeignKey("profiles.id"), nullable=False, index=True)
profile: Mapped[Profile] = relationship(back_populates="messages")
而且使用这个文件时,我遇到了循环导入的错误,我认为还会有很多其他需要与用户建立关系的表。
在使用Django时,有一个辅助函数 from django.contrib.auth import get\_user\_model,它可以接受用户应用的字符串位置,从而导入它,而不使用AUTH_USER_MODEL="users.User"。但这个函数对我来说有点难以理解,但也许有人能找到从字符串获取模型的方法(这会非常有用)
否则
是否有办法解决这个循环导入问题
解决方案
使用 字符串类型+ TYPE_CHECKING,不要在运行时导入模型。
users/models.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from app.wa_messages.models import WAMessage
class Profile(Base):
__tablename__ = "profiles"
messages: Mapped[list["WAMessage"]] = relationship(
"WAMessage", back_populates="profile", cascade="all, delete-orphan"
)
wa_messages/models.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from app.users.models import Profile
class WAMessage(Base):
__tablename__ = "wa_messages"
profile: Mapped["Profile"] = relationship(
"Profile", back_populates="messages"
)
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。