Usando OR en SQLAlchemy

He revisado los documentos y parece que no puedo descubrir 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 como

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

Desde el tutorial :

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

SQLAlchemy sobrecarga los operadores bitwise & , | y ~ así que en lugar de la syntax del prefijo feo y difícil de leer con or_() y and_() (como en la respuesta de Bastien ) puedes 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 a nivel de bits.

Así que toda tu consulta podría verse así:

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

El operador or_ 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ían 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_ puede reescribirse 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)) 

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) 

or_ esta es la función incorporada de sqlalchemy de sqlalchemy import or_

query = db.session.query (AddressBook) .filter (or_ (AddressBook.lastname == ‘bulger’, AddressBook.firstname == ‘whitey’)). filter (AddressBook.city == ‘boston’)