Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy-如何向查询添加动态左连接?_Python_Python 2.7_Sqlalchemy - Fatal编程技术网

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.