Mat*_*sen 2 python sqlalchemy python-2.7
我有六个表,建模如下:
+--< B >--C
|
A
|
+--< D >--E
Run Code Online (Sandbox Code Playgroud)
我希望能够动态查询以下任何选项:
A
A, B, C
A, D, E
A, B, C, D E
Run Code Online (Sandbox Code Playgroud)
例如,查询所有四个看起来像
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)
Run Code Online (Sandbox Code Playgroud)
我可以将模型附加到列表中并在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?
Run Code Online (Sandbox Code Playgroud)
我已经尝试了以下方法,但没有成功,即使有效,我也会假设 whenfoo和barare 的情况False都会留下一个空FROM子句。
q = q.select_from(*joins)
Run Code Online (Sandbox Code Playgroud)
当然,我可以在执行后删除joins列表并重复条件,如下所示,但我宁愿执行一次条件逻辑。ifq = session.query(*models)
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)
Run Code Online (Sandbox Code Playgroud)
每个outerjoin(以及其他 SLQALchemy 查询方法)都会修改一个query对象并返回一个新查询 - 您可以通过调用outerjoin(orfilter等...) 方法来进一步修改该查询。因此,只需使用 for 循环重复修改您的查询,并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.
Run Code Online (Sandbox Code Playgroud)