# order.py
class Order(Base):
__tablename__ = "Order"
id: Mapped[int] = mapped_column(primary_key=True)
items: Mapped[List["Item"]] = relationship(back_populates="order")
# item.py
class Item(Base):
__tablename__ = "Item"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
order_id: Mapped[int] = mapped_column(ForeignKey("Order.id"))
order: Mapped["Order"] = relationship(back_populates="items")
我正在使用 sqlalchemy 2.0.23,不使用 mypy 或 flake8 的插件。
两个模块都不需要导入另一个,因为我在 Order 类中使用字符串关系,例如“Item”,在 Item 类的关系中使用“Order”。
flake8 由于未定义名称而对两个文件报告 F821 错误。
mypy 在两者上都报告了类似的错误。
我可以配置 flake8 来忽略 F821。我不确定我会如何在 mypy 中做类似的事情。但这些重要的规则不应该被关闭以通过 linter 获取 SQLAlchemy 类。
我想将我的课程保存在单独的文件中。有没有办法正确定义它们,这样像这样的 linter 就不会抱怨?向这两个文件添加导入可以使这些 linter 安静下来,但会导致循环导入问题,因此代码将无法运行。
mypy
和 flake8
在这里是正确的,这些警告不应被忽略。要解决循环导入问题,您可以使用“仅类型检查导入”,即包装在 import
块中的 if TYPE_CHECKING
语句(TYPE_CHECKING
常量在 here 进行了解释)。它可能是这样的:
# order.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .item import Item
class Order(Base):
__tablename__ = "Order"
id: Mapped[int] = mapped_column(primary_key=True)
items: Mapped[List["Item"]] = relationship(back_populates="order")
和
# item.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .order import Order
class Item(Base):
__tablename__ = "Item"
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
order_id: Mapped[int] = mapped_column(ForeignKey("Order.id"))
order: Mapped["Order"] = relationship(back_populates="items")