outerjoins和别名混淆了FROM语句

时间:2013-10-07 20:16:09

标签: python sqlalchemy

我想加入查询中包含的多个表。其中一些连接将是别名。例如:

c_alias = aliased( C )
q = db.session.query( A, B, C ).join( A.some_things ).outerjoin(
    c_alias, and_(
        c_alias.b_id == B.id,
        c_alias.d_id == 1
    )
)

我希望这会产生如下的SQL:

SELECT
    a.id, b.id, c.id, ...
FROM
    a, b, c
    LEFT JOIN things ON things.a_id = a.id
    LEFT OUTER JOIN c AS c_alias ON c_alias.b_id = b.id AND c_alias.d_id = 1

但是,相反,bc表被删除了,我得到了类似的内容:

SELECT
    a.id, b.id, c.id, ...
FROM
    a, c
    LEFT JOIN things ON things.a_id = a.id
    LEFT OUTER JOIN c AS c_alias ON c_alias.b_id = b.id AND c_alias.d_id = 1

当然会抛出一个错误,因为从中选择了表b但从未查询过。默认情况下,A.some_things会被急切加载(在orm中通过lazy = 'joined')。

解决方法:

可以添加一个连接,并将条件设置为identity,以便人工查询所需的表。在这个例子中:

q = db.session.query( A, B, C ).join( B, B.id == B.id ).join( C, C.id == C.id )\
    .join( A.some_things ).outerjoin(
        c_alias, and_(
            c_alias.b_id == B.id,
            c_alias.d_id == 1
        )
    )

这会产生预期的结果,但会产生一些令人困惑的SQL,并且难以证明其合理性。

0 个答案:

没有答案