在SQLAlchemy中使用OR

310 投票
6 回答
317623 浏览
提问于 2025-04-17 05:16

我查阅了文档,但是找不到如何在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'))

撰写回答