SQLAlchemy:如何在没有额外查询的情况下将父 table 引用为关系

SQLAlchemy: how to reference the parent table as a relationship without an extra query

在 SQLAlchemy 中,我如何引用一个 table 已经加入关系而无需额外查询?

class CommonMetadata(Base):
    id = Column(Integer, primary_key=True)
    data = Column(String)


class Child(CommonMetadata):
    id = Column(Integer, ForeignKey("CommonMetadata.id"), primary_key=True)
    key = Column(String)
    common_metadata = relationship("CommonMetadata")

例如,当我这样做时:

child = session.query(Child).get(1)
child.common_metadata

尽管 Child 已经拥有该数据(因为它是 Child 和 CommonMetadata 的连接),但在访问 child.common_metadata 时完成了额外的连接。


SQLAlchemy 也不让我这样做:

child = session.query(Child).join(CommonMetadata).first()

由于 SQLAlchemy 注意到冗余连接:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.DuplicateAlias) table name "common" specified more than once

不过我可以这样做:

child, _ = session.query(Child, CommonMetadata).first()

但这不是最好的API。

为了使它自动工作,我需要在父项和子项上定义一个多态身份。

class CommonMetadata(Base):
    __mapper_args__ = {
        'polymorphic_identity': 'common_metadata',
    }

    id = Column(Integer, primary_key=True)
    data = Column(String)


class Child(CommonMetadata):
    __mapper_args__ = {
        'polymorphic_identity': 'child',
    }

    id = Column(Integer, ForeignKey("CommonMetadata.id"), primary_key=True)
    key = Column(String)
    common_metadata = relationship("CommonMetadata")

我不完全明白为什么,但我想这只是映射器的附加信息。