【问题标题】:Construct the entire tree from a SQLAlchemy adjacency list relationship从 SQLAlchemy 邻接列表关系构造整个树
【发布时间】:2011-04-15 17:47:05
【问题描述】:

我有一个类节点,它有一个自引用映射'children'(backref'parent'),代表 SQLAlchemy 中的一棵树,我想选择整个树。如果我这样做了

session.query(Node).all()

然后每次访问 node.children 都会触发一次选择。如果我做一个联合加载

session.query(Node).options(joinedload_all('children')).all()

然后发出的 sql 有一个不必要的表连接,因为无论如何我都想要整个树(所有节点)。有没有办法在 SA 中做到这一点,还是我应该在 SA 之外自己构建树?

【问题讨论】:

    标签: python sqlalchemy


    【解决方案1】:

    父属性没有问题,因为所需的所有信息都已加载到对象中。 SQLAlchemy 只需要在会话中查找父对象并仅在它丢失时才发出查询。但这对孩子不起作用:图书馆不能确定所有的孩子对象都已经在会话中。因此,您可以自己构建树并通过set_committed_value 指示 SQLAlchemy 使用这些数据:

    from collections import defaultdict
    from sqlalchemy.orm.attributes import set_committed_value
    
    nodes = session.query(Node).all()
    
    # Collect parent-child relations
    children = defaultdict(list)
    for node in nodes:
        if node.parent:
            children[node.parent.id].append(node)
    
    # Set collected values
    for node in nodes:
        set_committed_value(node, 'children', children[node.id])
    

    【讨论】:

    • 太棒了。我对自己构建树的犹豫正在弄脏节点对象,set_committed_value 是我需要的。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-07-11
    • 2013-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多