基本上,我有这个模型,我在一个表中映射了一个“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'))
使用此代码将抛出:
sqlalchemy.exc.ArgumentError:NodeTypeA.typeB_children和 反向引用NodeTypeB.parent_node都是相同的方向 。你的意思是设置remote_side 多对一的一方?
有任何想法或建议吗?
答案 0 :(得分: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)
请注意,manager
和manager_id
是“猴子修补的”,因为您无法在类定义中进行自引用。
所以在你的例子中,我猜这个:
class NodeTypeA(BaseNode):
__mapper_args__ = {'polymorphic_identity': 'NodeTypeA'}
typeB_children = relationship('NodeTypeB', backref='parent_node',
remote_side='NodeTypeB.parent_id')
编辑:基本上你的错误告诉你的是关系及其backref都是相同的。因此,无论SA采用什么规则来确定表级关系是什么,他们都不会对您提供的信息进行评估。
我了解到,简单地在声明性类中说mycolumn=relationship(OtherTable)
会导致mycolumn
成为列表,假设SA可以检测到明确的关系。因此,如果您确实希望对象具有指向其父级而不是其子级的链接,则可以在子表中定义parent=relationship(OtherTable, backref='children', remote_side=OtherTable.id)
。这定义了父子关系的两个方向。