sqlalchemy中的多态自引用外键

时间:2015-07-13 21:28:54

标签: python sql sqlalchemy foreign-keys

我正在尝试解决带有连接表继承的自引用表的问题,其中有一个链接继承关系的外键,但后面还有一个类有一个对其父实例的附加引用的情况。最好用简化的例子:

B类继承自A类.B类通过ID列通过B类中的外键链接到A类.B类还有一个列(a_id)引用A类,它没有任何内容。做继承。

from sqlalchemy import Column, Integer,ForeignKey, create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, backref

Base = declarative_base()


class A(Base):
    __tablename__ = 'a'
    satype = Column(String(50))
    __mapper_args__ = {
        'polymorphic_identity': 'a',
        'polymorphic_on': satype
    }

    id = Column(Integer, primary_key=True)


class B(A):
    __tablename__ = 'b'

    id = Column(Integer, ForeignKey('a.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'b'
    }

    a_id = Column(Integer, ForeignKey('a.id'))
    a = relationship('A', backref='b')

engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

根据the documentation,我将通过在要使用的关系中明确指定来解决表之间存在多个ForeignKeys的情况。

class B(A):
    __tablename__ = 'b'

    id = Column(Integer, ForeignKey('a.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'b'
    }

    a_id = Column(Integer, ForeignKey('a.id'))
    # I know the primaryjoin is no longer needed in SA >= 0.8
    a = relationship('A', backref='b', foreign_keys=[a_id], primaryjoin=a_id==A.id)

我认为问题在于我似乎无法弄清楚如何对多态列id做同样的事情,因为我没有明确定义这种关系。

1 个答案:

答案 0 :(得分:2)

感谢Michael Bayer在SA谷歌小组中的回答:

  

"相互依赖的外键"文件并不适用于   这个案例。这里发生的是B(A)需要从B到B的连接   A,然后B.a需要不同的。即使是惯例   这里明确哪个外键约束是哪个映射器   仍然需要明确说明它们,这就是:

class B(A):
    __tablename__ = 'b'

    id = Column(Integer, ForeignKey('a.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'b',
        'inherit_condition': id == A.id

    }

    a_id = Column(Integer, ForeignKey('a.id'))
    a = relationship(
        'A',
        backref='b', primaryjoin=A.id == a_id, remote_side=A.id)