【问题标题】:SQLAlchemy self-referential many-to-one relationship: exampleSQLAlchemy 自引用多对一关系:示例
【发布时间】:2019-05-03 02:10:34
【问题描述】:

当我关注 adjacency list relationships 上的 SQLAlchemy 文档时,我能够复制他们的 Node 示例,如下所示:

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

但是,我无法为多对一关系做同样的事情。这样的例子会是什么样子?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    使用上述链接中提供的示例和 多对一 类定义(唯一的区别是添加了 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到达作为起点的树。

    【讨论】:

    • 谢谢,解决了;您的示例与父(多对一),而不是双向示例。第一次阅读时我错过了。
    • 啊,我明白了。为了将来清楚起见,我添加了类 def。 :) 我也很感谢您的 {!r} 提示 - 从现在开始我将使用它。
    猜你喜欢
    • 1970-01-01
    • 2018-10-02
    • 2011-05-09
    • 2021-05-31
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2016-06-15
    • 2021-08-31
    相关资源
    最近更新 更多