如何在 SQLAlchemy 中处理循环导入

hau*_*gar 4 python sqlalchemy circular-dependency

我在 SQLAlchemy 中遇到循环导入问题。

我有两个文件 foo.py 和 bar.py。foo.py 定义了一个 SQLAlchemy 类 Foo,bar.py 定义了一个类 Bar。

Foo 和 Bar 都是彼此的外键,因此我将它们相互映射Mapped["..."]以获得类型安全,但这意味着我还需要导入实际的类。

这会导致循环导入错误。

处理这个问题的最佳方法是什么?在 SQLAlchemy 中处理循环导入的一般最佳实践有哪些?如果您双向使用关系,在这种情况下就不能保证类型安全吗?

# foo.py

from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from .bar import Bar

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    bar_id = Column(Integer, ForeignKey('bar.id'))
    bar: Mapped["Bar"] = relationship('Bar')

# bar.py

from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship
from .foo import Foo

class Bar(Base):
    __tablename__ = 'bar'
    id = Column(Integer, primary_key=True)
    foo_id = Column(Integer, ForeignKey('foo.id'))
    foo: Mapped["Foo"] = relationship('Foo')
Run Code Online (Sandbox Code Playgroud)

编辑:请注意,我无法删除 Bar 和 Foo 导入,因为那样Mapped["..."]会引发“...”的未定义错误

小智 5

您可以使用 TYPE_CHECKING。该常量在运行时为 False,但在 mypy(和其他类型检查工具)评估代码时为 True

from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
    from .bar import Bar
else:
    Bar = "Bar"

# foo.py

from sqlalchemy import Column, Integer, ForeignKey
from sqlalchemy.orm import relationship

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    bar_id = Column(Integer, ForeignKey('bar.id'))
    bar: Mapped[Bar] = relationship('Bar')
Run Code Online (Sandbox Code Playgroud)