在SQLAlchemy中使用OR
我查阅了文档,但是找不到如何在SQLAlchemy中进行OR查询的方法。我只是想做这个查询。
SELECT address FROM addressbook WHERE city='boston' AND (lastname='bulger' OR firstname='whitey')
应该类似于这个
addr = session.query(AddressBook).filter(City == "boston").filter(????)
6 个回答
60
or_()
函数在处理不确定数量的 OR 查询条件时非常有用。
举个例子,假设我们正在创建一个 REST 服务,这个服务有几个可选的过滤条件,只要其中任何一个条件满足,就应该返回记录。另一方面,如果请求中没有定义某个参数,我们的查询就不应该改变。如果没有 or_()
函数,我们必须这样做:
query = Book.query
if filter.title and filter.author:
query = query.filter((Book.title.ilike(filter.title))|(Book.author.ilike(filter.author)))
else if filter.title:
query = query.filter(Book.title.ilike(filter.title))
else if filter.author:
query = query.filter(Book.author.ilike(filter.author))
使用 or_()
函数后,可以改写成:
query = Book.query
not_null_filters = []
if filter.title:
not_null_filters.append(Book.title.ilike(filter.title))
if filter.author:
not_null_filters.append(Book.author.ilike(filter.author))
if len(not_null_filters) > 0:
query = query.filter(or_(*not_null_filters))
478
SQLAlchemy 对位运算符进行了重载,也就是说,它让我们可以用更简单的方式来写代码。比如,我们可以用 &
表示“与”,用 |
表示“或”,用 ~
表示“非”。这样,我们就不需要使用那些看起来复杂且难以阅读的 or_()
和 and_()
语法了(就像在 Bastien 的回答 中那样)。
.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))
需要注意的是,括号是必不可少的,因为位运算符的优先级问题。
所以你整个查询可能看起来像这样:
addr = session.query(AddressBook) \
.filter(AddressBook.city == "boston") \
.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))
534
来自教程的内容:
from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))