Python 如何在SQLAlchemy ORM中动态调整递归深度以进行急切加载?

Python 如何在SQLAlchemy ORM中动态调整递归深度以进行急切加载?,python,sqlalchemy,adjacency-list,recursive-query,Python,Sqlalchemy,Adjacency List,Recursive Query,我有一个两表的层次结构设置,其中表a引用表B,然后表B引用回表a中的另一条记录,以此类推。。。但仅限于给定的递归深度 我使用SQLAlchemy和声明式很好地实现了这一点。我还成功地使用了表关系上的lazy和join\u depth属性的渴望加载。这是根据 但是,这种安排在程序加载时将递归深度固定在“join\u depth”一次。。。但是对于我使用的数据,我知道每次应该使用的递归深度如何更改每个查询使用的递归深度? 我曾考虑过在基本ORM对象上修改masterjoin\u depth属性,但这

我有一个两表的层次结构设置,其中表a引用表B,然后表B引用回表a中的另一条记录,以此类推。。。但仅限于给定的递归深度

我使用SQLAlchemy和声明式很好地实现了这一点。我还成功地使用了表关系上的
lazy
join\u depth
属性的渴望加载。这是根据

但是,这种安排在程序加载时将递归深度固定在“
join\u depth
”一次。。。但是对于我使用的数据,我知道每次应该使用的递归深度如何更改每个查询使用的递归深度?

我曾考虑过在基本ORM对象上修改master
join\u depth
属性,但这不起作用,因为我有一个多线程作用域的会话应用程序,这会很危险(更不用说在运行时在SQLAlchemy中很难找到参数!)

我还研究了在查询中使用
joinedload
,但没有看到如何改变深度


我也知道,在一些数据库中,可以通过使用递归的SQL语法来使用“
”,但尽管它很好,我还是想暂时避免这种情况,因为一些数据库仍然不支持它(SQLAlchemy也不支持它——至少目前不支持,而且没有很多方言自定义)。

没有官方的方法可以做到这一点,但是遵循代码为我提供了以下解决方案。我使用的节点示例来自您链接的

class Node(Base):
    __tablename__ = 'node'
    id = Column(Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('node.id'))
    data = Column(String(50))
    children = relationship("Node",
                    lazy="joined",
                    join_depth=2)
在创建时,
children
属性的
join\u depth
值为2。此初始值记录在
节点.children.property.join\u depth
中。但是,更改此值不会起任何作用。在init,关系创建了一个用于加入的“策略”,并复制了
join\u depth
要更改关系策略的连接深度,请设置
节点.子项.属性.策略.连接深度

>>> engine.echo = True  # print generated queries
>>> session.query(Node).all()  # with default join_depth
SELECT node.id AS node_id, node.parent_id AS node_parent_id, node.data AS node_data, node_1.id AS node_1_id, node_1.parent_id AS node_1_parent_id, node_1.data AS node_1_data, node_2.id AS node_2_id, node_2.parent_id AS node_2_parent_id, node_2.data AS node_2_data FROM node LEFT OUTER JOIN node AS node_2 ON node.id = node_2.parent_id LEFT OUTER JOIN node AS node_1 ON node_2.id = node_1.parent_id
>>> Node.children.property.strategy.join_depth = 4  # new join depth
>>> session.query(Node).all()  # with new join depth
SELECT node.id AS node_id, node.parent_id AS node_parent_id, node.data AS node_data, node_1.id AS node_1_id, node_1.parent_id AS node_1_parent_id, node_1.data AS node_1_data, node_2.id AS node_2_id, node_2.parent_id AS node_2_parent_id, node_2.data AS node_2_data, node_3.id AS node_3_id, node_3.parent_id AS node_3_parent_id, node_3.data AS node_3_data, node_4.id AS node_4_id, node_4.parent_id AS node_4_parent_id, node_4.data AS node_4_data FROM node LEFT OUTER JOIN node AS node_4 ON node.id = node_4.parent_id LEFT OUTER JOIN node AS node_3 ON node_4.id = node_3.parent_id LEFT OUTER JOIN node AS node_2 ON node_3.id = node_2.parent_id LEFT OUTER JOIN node AS node_1 ON node_2.id = node_1.parent_id
设置
Node.children.property.strategy.join\u depth
后,生成的查询中的连接数也会发生变化