SQLAlchemy - 如何向查询添加动态左连接?

2024-04-03

我有六个表,建模如下:

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

我希望能够动态查询以下任何选项:

A
A, B, C
A, D, E
A, B, C, 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 and bar都是False会留下一个空的FROM clause.

q = q.select_from(*joins)

我当然可以摆脱joins列出并重复if执行后的条件q = 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)

Each outerjoin(和其他 SQLALchemy 查询方法)修改query对象并返回一个新查询 - 您可以通过调用进一步修改该查询outerjoin (or filter等...)方法。 因此,只需使用 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.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SQLAlchemy - 如何向查询添加动态左连接? 的相关文章

随机推荐