SQLAlchemy单表继承上的一对多关系 - 声明式

ped*_*idi 11 python orm sqlalchemy

基本上,我有这个模型,我在一个表中映射了一个"BaseNode"类和两个子类.关键是我需要其中一个子类,与另一个子类具有一对多的关系.所以在排序中,它是与另一行不同类(子类)的关系,但在同一个表中.您认为我怎么能用声明性语法编写它?

注意:由于我的模型中的其他关系,如果可能,我真的需要坚持单表继承.

class BaseNode(DBBase):
    __tablename__ = 'base_node'
    id = Column(Integer, primary_key=True)
    discriminator = Column('type', String(50))
    __mapper_args__ = {'polymorphic_on': discriminator}

class NodeTypeA(BaseNode):
    __mapper_args__ = {'polymorphic_identity': 'NodeTypeA'}
    typeB_children = relationship('NodeTypeB', backref='parent_node')


class NodeTypeB(BaseNode):
    __mapper_args__ = {'polymorphic_identity': 'NodeTypeB'}
    parent_id = Column(Integer, ForeignKey('base_node.id'))
Run Code Online (Sandbox Code Playgroud)

使用此代码将抛出:

sqlalchemy.exc.ArgumentError:NodeTypeA.typeB_children和反向引用NodeTypeB.parent_node都是相同的方向.你的意思是在多对一方设置remote_side吗?

任何想法或建议?

wbe*_*rry 12

我之前正在努力解决这个问题.我能够让这种自我指涉关系发挥作用:

class Employee(Base):
  __tablename__ = 'employee'
  id = Column(Integer, primary_key=True)
  name = Column(String(64), nullable=False)
Employee.manager_id = Column(Integer, ForeignKey(Employee.id))
Employee.manager = relationship(Employee, backref='subordinates',
    remote_side=Employee.id)
Run Code Online (Sandbox Code Playgroud)

请注意,manager并且manager_id是"猴子修补",因为您无法在类定义中进行自引用.

所以在你的例子中,我猜这个:

class NodeTypeA(BaseNode):
    __mapper_args__ = {'polymorphic_identity': 'NodeTypeA'}
    typeB_children = relationship('NodeTypeB', backref='parent_node',
        remote_side='NodeTypeB.parent_id')
Run Code Online (Sandbox Code Playgroud)

编辑:基本上你的错误告诉你的是关系和它的backref是相同的.因此,无论SA使用何种规则来确定表级关系是什么,他们都不会对您提供的信息进行评分.

我了解到,只要mycolumn=relationship(OtherTable)在声明性类中说,就会产生mycolumn一个列表,假设SA可以检测到明确的关系.因此,如果您确实希望对象具有指向其父级而不是其子级的链接,则可以parent=relationship(OtherTable, backref='children', remote_side=OtherTable.id)在子表中进行定义.这定义了父子关系的两个方向.

  • 可以在没有“猴子修补”的情况下定义自引用关系 - 使用本地或文本引用:`manager_id = Column(Integer,ForeignKey(id))`和`manager=relationship("Employee", backref='subscribeds',远程端=id)` (3认同)
  • SQLAlchemy文档说,可以提供评估得到的字符串,这样您就可以避免自引用语法错误。但我从未尝试过。 (2认同)