Python SQLAlchemy自参考多对一关系:示例

Python SQLAlchemy自参考多对一关系:示例,python,sqlalchemy,Python,Sqlalchemy,当我在上阅读SQLAlchemy文档时,我能够复制它们的节点示例,如下所示: node_tree = Node(data='root', children=[ Node(data='child1'), Node(data='child2', children=[ Node(data='subchild1'), Node(data='subchild2'), ]), Node(data='child3'), ]) 然而,对于多对一的

当我在上阅读SQLAlchemy文档时,我能够复制它们的
节点
示例,如下所示:

node_tree = Node(data='root', children=[
    Node(data='child1'),
    Node(data='child2', children=[
        Node(data='subchild1'),
        Node(data='subchild2'),
    ]),
    Node(data='child3'),
])

然而,对于多对一的关系,我无法做到同样的事情。这个例子会是什么样子?

从前面链接提供的示例和多对一类定义开始工作(唯一的区别是添加了
remote\u-side
参数),再加上一个用于可视化的漂亮的
\u-repr\u

class Node(Base):
    __tablename__ = 'node'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('node.id'))
    data = Column(String(50))
    parent = relationship("Node", remote_side=[id])

    def __repr__(self):
        return "Node(data={!r})".format(self.data)

# Create tree.
node_tree = Node(data='root')
child1 = Node(data='child1', parent=node_tree)
child2 = Node(data='child2', parent=node_tree)
subchild1 = Node(data='subchild1', parent=child2)
subchild2 = Node(data='subchild2', parent=child2)
child3 = Node(data='child3', parent=node_tree)

# For viewing the session as it works.
def print_session_state(operation):
    print(operation)
    print('new: {}'.format(session.new))
    print('dirty: {}\n'.format(session.dirty))

# When child2 is added...
session.add(child2)
print_session_state('add child2')
# Roll back.
session.rollback()
print_session_state('rollback')
# When subchild1 is added...
session.add(subchild1)
print_session_state('add subchild1')
结果是:

add child2
new: IdentitySet([Node(data='child2'), Node(data='root')])
dirty: IdentitySet([])

rollback
new: IdentitySet([])
dirty: IdentitySet([])

add subchild1
new: IdentitySet([Node(data='subchild1'), Node(data='child2'), Node(data='root')])
dirty: IdentitySet([])
您会注意到的第一件事是实例化没有那么漂亮,因为层次结构这次是自下而上定义的

此外,级联行为也不同。在一对多关系中,每个
节点都知道它的子节点(复数),级联沿着树向下移动


对于多对一,每个
节点
只知道它的父节点(单数),级联在树上向上移动,这样就只到达树的同一分支中作为起点的那些
节点。

谢谢,这就清除了它;您的示例仅包含父对象(多对一),而不是双向示例。我第一次通读的时候就错过了。啊,我现在明白了。我添加了类def,以便将来更清晰明了。:)我也很感激你的
{!r}
技巧——从现在起我将使用它。