29

连接 2 个表时如何在 ON 子句中添加 2 个条件。我在层次结构中有 3 个三个表,每个表都带有已删除的标志。我必须在一个查询中加入所有这些表,并根据已删除标志进行过滤。目前,条件被添加到查询的 where 子句中,它不会过滤已删除的记录。它需要添加到 ON 子句中。请建议。

我目前的查询如下:

result = session.query(Host).filter(and_(Host.id.in_(ids), Host.deleted == False)).\
    join(Switch).filter(Switch.deleted == False).\
    join(Port).filter(Port.deleted == False).\
    options(joinedload('switches')).\
    options(joinedload('ports')).\
    all()

谢谢

4

3 回答 3

52

尝试 contains_eager 而不是joinedload。可能发生的情况是您有 4 个连接,您使用 join 定义的两个连接,然后是 options(joinedload(...)) 中的两个连接

修改你的代码,应该给出这个:

from sqlalchemy import and_

result = (session.query(Host).filter(and_(Host.id.in_(ids), Host.deleted == False)).
    join(Switch, and_(Switch.host_id==Host.id, Switch.deleted == False)).
    join(Port, and_(Port.switch_id==Switch.id, Port.deleted == False)).
    options(contains_eager('switches')).
    options(contains_eager('ports')).
    all()
)
于 2012-06-27T23:55:08.993 回答
24

and_() 连词也可以使用 Python & 运算符(但请注意,复合表达式需要用括号括起来才能使用 Python 运算符优先级行为):还有| 对于 or_()~ 对于 not_()

因此,使用 & 运算符,您的代码将如下所示:

result = session.query(Host).filter(Host.id.in_(ids) & (Host.deleted == False)).
    join(Switch, (Switch.host_id==Host.id) & (Switch.deleted == False)).
    join(Port, (Port.switch_id==Switch.id) & (Port.deleted == False)).
    options(contains_eager('switches')).
    options(contains_eager('ports')).
    all()
)
于 2017-10-12T19:47:13.603 回答
7

您可以使用参数在调用中ON明确指定子句。然后您的查询应如下所示(未经测试):Query.joinonclause

from sqlalchemy import and_

result = (session.query(Host).filter(and_(Host.id.in_(ids), Host.deleted == False)).
    join(Switch, and_(Switch.host_id==Host.id, Switch.deleted == False)).
    join(Port, and_(Port.switch_id==Switch.id, Port.deleted == False)).
    options(joinedload('switches')).
    options(joinedload('ports')).
    all()
)
于 2012-06-22T10:35:21.287 回答