在SQLAlchemy中使用OR

时间:2011-10-30 00:17:28

标签: python sqlalchemy

我看了through the docs,我似乎无法找到如何在SQLAlchemy中进行OR查询。我只是想做这个查询。

SELECT address FROM addressbook WHERE city='boston' AND (lastname='bulger' OR firstname='whitey')

应该像

addr = session.query(AddressBook).filter(City == "boston").filter(????)

5 个答案:

答案 0 :(得分:281)

SQLAlchemy重载按位运算符&|~,而不是使用or_()and_()的难看且难以阅读的前缀语法(比如Bastien's answer)你可以使用这些运算符:

.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

请注意,由于按位运算符的优先级,括号不是可选的

所以你的整个查询看起来像这样:

addr = session.query(AddressBook) \
    .filter(AddressBook.city == "boston") \
    .filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))

答案 1 :(得分:273)

来自tutorial

from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))

答案 2 :(得分:25)

如果OR查询组件数量未知,则

or_运算符非常有用。

例如,假设我们正在创建一个包含很少可选过滤器的REST服务,如果任何过滤器返回true,则应返回记录。另一方面,如果请求中未定义参数,则不应更改我们的查询。没有or_ function我们必须做这样的事情:

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))

答案 3 :(得分:3)

这真的很有帮助。 这是我对任何给定表的实现:

def sql_replace(self, tableobject, dictargs):

    #missing check of table object is valid
    primarykeys = [key.name for key in inspect(tableobject).primary_key]

    filterargs = []
    for primkeys in primarykeys:
        if dictargs[primkeys] is not None:
            filterargs.append(getattr(db.RT_eqmtvsdata, primkeys) == dictargs[primkeys])
        else:
            return

    query = select([db.RT_eqmtvsdata]).where(and_(*filterargs))

    if self.r_ExecuteAndErrorChk2(query)[primarykeys[0]] is not None:
        # update
        filter = and_(*filterargs)
        query = tableobject.__table__.update().values(dictargs).where(filter)
        return self.w_ExecuteAndErrorChk2(query)

    else:
        query = tableobject.__table__.insert().values(dictargs)
        return self.w_ExecuteAndErrorChk2(query)

# example usage
inrow = {'eqmtvs_id': eqmtvsid, 'datetime': dtime, 'param_id': paramid}

self.sql_replace(tableobject=db.RT_eqmtvsdata, dictargs=inrow)

答案 4 :(得分:0)

对于 SQLAlchemy ORM 2.0,|or_ 都被接受。

Documentation

from sqlalchemy.future import select
from sqlalchemy.sql import or_


query = select(User).where(or_(User.name == 'ed', User.name == 'wendy'))
print(query)

# also possible:

query = select(User).where((User.name == 'ed') | (User.name == 'wendy'))
print(query)