使用上述链接中提供的示例和 多对一 类定义(唯一的区别是添加了 remote_side 参数),以及用于可视化的漂亮 __repr__...
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([])
您会注意到的第一件事是实例化并不那么漂亮,因为这次层次结构是自下而上定义的。
此外,级联行为也不同。在一对多的关系中,每个Node 都知道它的孩子(复数)并且级联沿着树向下传播。
对于多对一,每个Node 只知道它的父级(单数)并且级联向上传播,这样只有在同一分支中的Nodes到达作为起点的树。