[英]Using SQLAlchemy with multiple self-referential foreign keys
What if I had something like a double linked list in a relational database, for example: 如果我在关系数据库中有类似双链表的内容,例如:
node_id left_id right_id
1 null 2
2 1 3
3 2 null
Then I have some SQLAlchemy code like the following: 然后我有一些SQLAlchemy代码,如下所示:
class NodeClass(Base):
__tablename__ = 'nodes_table'
node_id = Column(Integer, primary_key=True)
left_id = Column(Integer, ForeignKey('nodes_table.node_id'))
right_id = Column(Integer, ForeignKey('nodes_table.node_id'))
left = relationship('NodeClass') # Wrong
right = relationship('NodeClass') # Wrong
If I have node_id 2, and I call NodeClass.left
I would like to receive node_id 1 in return. 如果我有node_id 2,我调用
NodeClass.left
我想收到node_id 1作为回报。 How can I configure the SQLAlchemy relationships to behave this way? 如何配置SQLAlchemy关系以这种方式运行?
UPDATE: 更新:
I will give a second example. 我将举一个例子。 Consider a table of people, and each person has a mother and a father.
考虑一张人的表,每个人都有一个母亲和一个父亲。
person_id mother_id father_id
1 null null
2 null null
3 1 2
The SQLAlchemy code: SQLAlchemy代码:
class PersonClass(Base):
__tablename__ = 'persons_table'
person_id = Column(Integer, primary_key=True)
mother_id = Column(Integer, ForeignKey('persons_table.person_id'))
father_id = Column(Integer, ForeignKey('persons_table.person_id'))
mother = relation('PersonClass') # Wrong
father = relation('PersonClass') # Wrong
The code below shows how to configure the relationship: 下面的代码显示了如何配置关系:
class NodeClass(Base):
__tablename__ = 'nodes_table'
node_id = Column(Integer, primary_key=True)
left_id = Column(Integer, ForeignKey('nodes_table.node_id'))
left = relationship('NodeClass', remote_side=[node_id],
primaryjoin=('NodeClass.left_id==NodeClass.node_id'),
backref=backref("right", uselist=False),
#lazy="joined", join_depth=9,
)
But few things should be noted: 但是应该注意的事情很少:
myNode.left = myOtherNode
and the other ( right
) will be set automatically (because of configured backref
) myNode.left = myOtherNode
就可以了,另一方( right
)将自动设置(因为配置了backref
) right
and left
), then right
和left
),那么
insert-1, insert-2, update-1
in case your primary key is computed on the database, as it is unknown during the first insert
. insert-1, insert-2, update-1
,因为在第一次insert
期间它是未知的。 UPDATE: Sample code to the UPDATE part of the question (but still using the original class name). 更新:问题的UPDATE部分的示例代码(但仍使用原始类名)。 One needs only to specify the
primaryjoin
and uselist=False
: 人们只需要指定
primaryjoin
和uselist=False
:
class NodeClass(Base):
__tablename__ = 'nodes_table'
node_id = Column(Integer, primary_key=True)
left_id = Column(Integer, ForeignKey('nodes_table.node_id'))
right_id = Column(Integer, ForeignKey('nodes_table.node_id'))
left = relationship('NodeClass', primaryjoin = ('NodeClass.left_id == NodeClass.node_id'), use_list=False)
right = relationship('NodeClass', primaryjoin = ('NodeClass.right_id == NodeClass.node_id'), use_list=False)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.