SQL Alchemy处理邻接结构就好了,例如一个自引用表节点,其中外键node.parent_id与主键node.id相关。
我有一个不那么传统的模型,其中一个节点有两个父母(一个家谱数据库)。在此,node.mat_id和node.pat_id分别与母系和父系父节点相关。 SQL Alchemy也可以这样做:
mother = db.relationship("Node",
foreign_keys = "Node.mat_id", remote_side="Node.id")
father = db.relationship("Node",
foreign_keys = "Node.pat_id", remote_side="Node.id")
(使用声明)。
因此获得一个节点的父母是直截了当的。我的问题是通过此设置获取节点的子节点。我找不到建立关系的方法,相当于:
offspring = db.relationship("Node",
foreign_keys = "Node.mat_id | Node.pat_id")
我管理的最好的方法是分别声明mat_offspring和pat_offspring关系,并创建一个返回适当的成员函数offspring()。它有效,但似乎不优雅。有更好,更传统的方式吗?
鉴于原始架构限制,您走在了正确的轨道上。而不是foreign_keys
你将传递加入条件作为primaryjoin
:
class Node(Base):
__tablename__ = "node"
id = Column(Integer, primary_key=True)
mat_id = Column(ForeignKey(id))
pat_id = Column(ForeignKey(id))
mother = relationship("Node", foreign_keys=[mat_id], remote_side=id)
father = relationship("Node", foreign_keys=[pat_id], remote_side=id)
offspring = relationship("Node",
primaryjoin=or_(id == mat_id, id == pat_id),
viewonly=True)
请注意,由于更复杂的连接条件,关系定义为view only。换句话说,你不能简单地通过它将后代添加到Node,因为你不能说父节点是新添加的后代的父亲还是母亲。在这个意义上,你原来独立的母系和父系关系是优越的。