Python SQLAlchemy-如何向查询添加动态左连接?
我有六个表,模型如下:Python SQLAlchemy-如何向查询添加动态左连接?,python,python-2.7,sqlalchemy,Python,Python 2.7,Sqlalchemy,我有六个表,模型如下: +--< B >--C | A | +--< D >--E 例如,查询所有四个 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子
+--< B >--C
|
A
|
+--< D >--E
例如,查询所有四个
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?
我尝试了以下方法,但没有成功,即使成功了,我也会假设当foo
和bar
都是False
时,会留下一个空的FROM
子句
q = q.select_from(*joins)
当然,在执行q=session.query(*models)
之后,我可以去掉连接
列表并重复if
条件,如下所示,但我宁愿执行一次条件逻辑
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)
每个
outerjoin
(和其他SLQALchemy查询方法)修改query
对象并返回一个新的查询-您可以通过调用上的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.
@jsbueno验证的答案给了我一个解决问题的提示,但它并没有100%对我有效。可能是版本问题,所以提供了一个几乎类似的解决方案,对我来说很有效
models = [A]
joins = []
if foo:
joins.append((B, A.id == B.a_id))
joins.append((C, C.id == B.c_id))
if bar:
joins.append((D, A.id == D.d_id))
joins.append((E, E.id == D.e_id))
q = session.query(*models)
for join_args in joins:
q = q.outerjoin(*join_args)
q.all() #This shall give you the required output.
它不返回新查询,而是返回一个连接对象
models = [A]
joins = []
if foo:
joins.append((B, A.id == B.a_id))
joins.append((C, C.id == B.c_id))
if bar:
joins.append((D, A.id == D.d_id))
joins.append((E, E.id == D.e_id))
q = session.query(*models)
for join_args in joins:
q = q.outerjoin(*join_args)
q.all() #This shall give you the required output.