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'))
Using this code will throw:
sqlalchemy.exc.ArgumentError: NodeTypeA.typeB_children and
back-reference NodeTypeB.parent_node are both of the same direction
. Did you mean to set remote_side on the
many-to-one side ?
Any ideas or suggestions?
I was struggling through this myself earlier. I was able to get this self-referential relationship working:
Note that the
managerandmanager_idare “monkey-patched” because you cannot make self-references within a class definition.So in your example, I would guess this:
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.
I learned that simply saying
mycolumn=relationship(OtherTable)in your declarative class will result inmycolumnbeing 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 defineparent=relationship(OtherTable, backref='children', remote_side=OtherTable.id)in the child table. That defines both directions of the parent-child relationship.