2016-06-18 8 views
2

私は次のようにモデル化された6つのテーブル、持っている:私は動的にこれらのオプションのいずれかの照会できるようにしたいと思いSQLAlchemy - 動的左結合をクエリに追加する方法

+--<B>--C 
| 
A 
| 
+--<D>--E 

を:たとえば

A 
A, B, C 
A, D, E 
A, B, C, D E 

を、4つのすべてを照会することは

ようになります。
q = session.query(A, B, C, D, E) \ 
    .outerjoin(B, A.id == B.a_id).outerjoin(C, C.id == B.c_id) 
    .outerjoin(D, A.id == D.a_id).outerjoin(E, E.id == D.e_id) 

モデルをリストに追加し、select節で動的に使用することができます。しかし、私はどのように動的に結合を添付するのか分かりません。ここで私はこれまで持っているものです。

from sqlalchemy import outerjoin 

models = [A] 
joins = [] 

if foo: 
    models.append(B) 
    models.append(C) 
    joins.append(outerjoin(A, B, A.id == B.a_id)) 
    joins.append(outerjoin(B, C, C.id == B.c_id)) 

if bar: 
    models.append(D) 
    models.append(E) 
    joins.append(outerjoin(A, D, A.id == D.d_id)) 
    joins.append(outerjoin(D, E, E.id == D.e_id)) 

q = session.query(*models) 
# How do I attach my joins list to this query? 

私は動作しませんでしたし、それがなかった場合でも、私はfoobarは両方Falseている場合は、空のFROM句を残すだろうと推測う以下を、試してみました。もちろん

q = q.select_from(*joins) 

私はjoinsリストを取り除くと、以下のように、q = session.query(*models)を実行した後if条件を繰り返したが、私はむしろ、条件ロジック1時間を実行することになり得ることができます。

if foo: 
    q = q.outerjoin(B, A.id == B.a_id).outerjoin(C, C.id == B.c_id) 

if bar: 
    q = q.outerjoin(D, A.id == D.a_id).outerjoin(E, E.id == D.e_id) 

答えて

2

outerjoin(および他のSLQALchemyのクエリーメソッドは)queryオブジェクトを変更し、新しいクエリを返します - あなたは、さらに(...など、またはfilter)のメソッドをouterjoinを呼び出すことによって変更することができます。 したがって、forループを使用して、条件で指定した各outerjoinパラメータのセットごとに、クエリを繰り返しouterjoinに繰り返し変更してください。パラメータそのものは、モデルの場合と同じように、*でプリペンドするタプルだけでもかまいません。

models = [A] 
joins = [] 

if foo: 
    models.append(B) 
    models.append(C) 
    joins.append((A, B, A.id == B.a_id)) 
    joins.append((B, C, C.id == B.c_id)) 

if bar: 
    models.append(D) 
    models.append(E) 
    joins.append((A, D, A.id == D.d_id)) 
    joins.append((D, E, E.id == D.e_id)) 

q = session.query(*models) 
for join_args in joins: 
    q = q.outerjoin(*join_args) 

# q is now ready to go with all outerjoins specified. 
関連する問題