我有多对多的联结表,类似于以下内容:
FooBar
-----------------------
id | foo_id | bar_id
1 | 1 | 1
2 | 1 | 2
3 | 2 | 3
4 | 3 | 4
以及(foo_id, bar_id)
的列表,例如:
items = [(1, 1), (1, 2), (2, 3), (3, 4)
如何在SQLAlachemy中执行以下查询?
SELECT id
FROM foo_bar
WHERE (foo_id = 1 AND bar_id = 1)
OR (foo_id = 1 AND bar_id = 2)
OR (foo_id = 2 AND bar_id = 3)
OR (foo_id = 3 AND bat_id = 4)
我尝试了以下变体,但它们都返回一个仅包含ANDs
的WHERE子句from sqlalchemy import and_, or_
q = session.query(FooBar)
for item in items:
q = q.filter(or_(and_(FooBar.foo_id == item[0], FooBar.bar_id == item[1])))
print q.statement
for item in
答案 0 :(得分:2)
问题在于,使用单个表达式调用or_()
基本上只是表达式,因为没有任何与OR有关。重复调用Query.filter()
会附加与AND结合的新谓词。将迭代移到filter(or_())
:
q = q.filter(or_(*(and_(FooBar.foo_id == foo_id, FooBar.bar_id == bar_id)
for foo_id, bar_id in items)))
这将生成一个生成器表达式,然后将其解压缩为or_()
的位置参数。
如果使用支持复合IN结构的后端,例如Postgresql和MySQL,则可以将其替换为tuple_().in_
:
from sqlalchemy import tuple_
...
q = q.filter(tuple_(FooBar.foo_id, FooBar.bar_id).in_(items))