本文介绍了单表继承上的SQLAlchemy一对多关系-声明性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我有这个模型,我在一个表中映射了一个"BaseNode"类和两个子类.关键是我需要一个子类与另一个子类建立一对多关系.因此,从某种意义上说,它是与同一类表中不同类(子类)的另一行的关系.您如何看待我可以使用声明性语法来编写它?.

Basically, I have this model, where I mapped in a single table a "BaseNode" class, and two subclasses. The point is that I need one of the subclasses, to have a one-to-many relationship with the other subclass.So in sort, it is a relationship with another row of different class (subclass), but in the same table.How do you think I could write it using declarative syntax?.

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

Note: Due to other relationships in my model, if it is possible, I really need to stick with single table inheritance.

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'))

使用此代码将引发:

有什么想法或建议吗?

推荐答案

我本人早些时候在为此苦苦挣扎.我能够使这种自我参照关系起作用:

I was struggling through this myself earlier. I was able to get this self-referential relationship working:

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)

请注意,managermanager_id是猴子修补的",因为您不能在类定义中进行自引用.

Note that the manager and manager_id are "monkey-patched" because you cannot make self-references within a class definition.

所以在您的示例中,我会这样猜测:

So in your example, I would guess this:

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

编辑:基本上,您的错误告诉您的是关系及其反向引用都是相同的.因此,无论SA采取什么规则来弄清表级关系是什么,它们都不会与您提供的信息保持一致.

EDIT: Basically what your error is telling you is that the relationship and its backref are both identical. So whatever rules that SA is applying to figure out what the table-level relationships are, they don't jive with the information you are providing.

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

I learned that simply saying mycolumn=relationship(OtherTable) in your declarative class will result in mycolumn being a list, assuming that SA can detect an unambiguous relationship. So if you really want an object to have a link to its parent, rather than its children, you can define parent=relationship(OtherTable, backref='children', remote_side=OtherTable.id) in the child table. That defines both directions of the parent-child relationship.

这篇关于单表继承上的SQLAlchemy一对多关系-声明性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-11 10:53