Ответ 1
Из tutorial:
from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))
Я просмотрел через документы, и я не могу найти, как выполнить запрос OR в SQLAlchemy. Я просто хочу сделать этот запрос.
SELECT address FROM addressbook WHERE city='boston' AND (lastname='bulger' OR firstname='whitey')
Должно быть что-то вроде
addr = session.query(AddressBook).filter(City == "boston").filter(????)
Из tutorial:
from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))
SQLAlchemy перегружает побитовые операторы &
, |
и ~
, поэтому вместо уродливого и трудно читаемого синтаксиса префикса с помощью or_()
и and_()
(например, в Bastien answer), вы можете использовать следующие операторы:
.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))
Обратите внимание, что круглые скобки не являются обязательными из-за приоритета побитовых операторов.
Таким образом, весь ваш запрос может выглядеть так:
addr = session.query(AddressBook) \
.filter(AddressBook.city == "boston") \
.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))
Функция or_()
может быть полезна в случае неизвестного количества компонентов запроса ИЛИ.
Например, предположим, что мы создаем службу REST с несколькими дополнительными фильтрами, которые должны возвращать запись, если какой-либо из фильтров возвращает значение true. С другой стороны, если параметр не был определен в запросе, наш запрос не должен изменяться. Без функции 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))
Это действительно помогло. Вот моя реализация для любой таблицы:
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)