python - how - Usando OR en SQLAlchemy
sqlalchemy for dummies (4)
Del tutorial :
from sqlalchemy import or_
filter(or_(User.name == ''ed'', User.name == ''wendy''))
He revisado los documentos y parece que no sé cómo hacer una consulta OR en SQLAlchemy. Solo quiero hacer esta consulta.
SELECT address FROM addressbook WHERE city=''boston'' AND (lastname=''bulger'' OR firstname=''whitey'')
Debería ser algo así como
addr = session.query(AddressBook).filter(City == "boston").filter(????)
Esto ha sido realmente útil. Aquí está mi implementación para cualquier tabla dada:
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)
SQLAlchemy sobrecarga los operadores bit a bit &
, |
y ~
entonces en lugar de la sintaxis de prefijo feo y difícil de leer con or_()
y and_()
(como en la respuesta de Bastien ) puede usar estos operadores:
.filter((AddressBook.lastname == ''bulger'') | (AddressBook.firstname == ''whitey''))
Tenga en cuenta que los paréntesis no son opcionales debido a la precedencia de los operadores bit a bit.
Por lo tanto, toda su consulta podría verse así:
addr = session.query(AddressBook) /
.filter(AddressBook.city == "boston") /
.filter((AddressBook.lastname == ''bulger'') | (AddressBook.firstname == ''whitey''))
or_ operator puede ser útil en caso de un número desconocido de componentes de consulta OR.
Por ejemplo, supongamos que estamos creando un servicio REST con pocos filtros opcionales, que debería devolver el registro si alguno de los filtros devuelve verdadero. Por otro lado, si el parámetro no se definió en una solicitud, nuestra consulta no debería cambiar. Sin la función or_ debemos hacer algo como esto:
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))
Con la función or_ se puede reescribir a:
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))