2010-12-07 10 views
6

私はテーブルAがテーブルBを参照し、テーブルAの別のレコードに戻って参照するという2つのテーブルの階層的な設定をしていますが...しかし、特定の再帰深度までです。SQLAlchemy ORMで熱心な負荷の再帰深さを動的に調整するにはどうすればよいですか?

私はSQLAlchemyと宣言を使用してこれをうまく利用しています。私はまた、テーブル関係についてlazyjoin_depthのプロパティを持つ熱心な読み込みをうまく使っています。これはSQLAlchemy documentationのとおりです。

しかし、この構成では、プログラムの読み込み時に 'join_depth'に再帰深度を固定しますが、私が使用しているデータでは、毎回使用するはずの再帰の深さを知っています。 クエリ単位で使用される再帰の深さを変更するにはどうすればよいですか?

ベースORMオブジェクトのマスターjoin_depthプロパティでの操作を検討しましたが、これは危険です(マルチスレッドのscoped_sessionアプリケーションがあるため動作しません)。パラメータは実行時にSQLAlchemy内で見つけにくいです!)。

また、joinedloadをクエリで使用してみましたが、その深さをどのように変更するかはわかりません。

CTEsを介して一部のデータベースで利用可能なSQL構文「WITH RECURSIVE」も知っていますが、それなりの価値がありますが、一部のデータベースではこれをサポートしていないため、 SQLAlchemyは、少なくとも現時点ではなく、多くの方言のカスタマイズがないわけではありません。

答えて

3

これを行う公式の方法はありませんが、コードに従って、私にとっては次の解決策が得られました。リンクしたdocsのノードの例を使用しています。

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プロパティは、この初期値はNode.children.property.join_depthに記録されている2のjoin_depth与えられています。ただし、この値を変更しても何も行われません。 initで、関係は結合のための "戦略"を作成し、これはjoin_depthの値をコピーします。 リレーションシップの戦略の結合の深さを変更するには、Node.children.property.strategy.join_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_depthを設定した後、生成されたクエリに参加の数も同様に変化します。

関連する問題