Pra*_*nsr 17 python sqlalchemy
如何在连接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()
Run Code Online (Sandbox Code Playgroud)
谢谢
Ton*_*bbs 33
尝试使用contains_eager而不是joinedload.可能发生的是你有4个连接你用join定义的两个,然后是两个来自选项(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()
)
Run Code Online (Sandbox Code Playgroud)
该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()
)
Run Code Online (Sandbox Code Playgroud)
您可以ON在Query.joincall using using onclause参数中明确指定子句.然后你查询应该如下所示(未测试):
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()
)
Run Code Online (Sandbox Code Playgroud)