J'ai regardé à travers la documentation et je n'arrive pas à trouver comment faire une requête OR dans SQLAlchemy. Je veux juste faire cette requête.
SELECT address FROM addressbook WHERE city='boston' AND (lastname='bulger' OR firstname='whitey')
Devrait être quelque chose comme
addr = session.query(AddressBook).filter(City == "boston").filter(????)
De la tutoriel :
from sqlalchemy import or_
filter(or_(User.name == 'ed', User.name == 'wendy'))
SQLAlchemy surcharge les opérateurs au niveau des bits &
, |
et ~
donc au lieu de la syntaxe de préfixe laide et difficile à lire avec or_()
et and_()
(comme dans Réponse de Bastien ) vous pouvez utiliser ces opérateurs:
.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))
Notez que les parenthèses ne sont pas facultatives en raison de la priorité des opérateurs au niveau du bit.
Donc, toute votre requête pourrait ressembler à ceci:
addr = session.query(AddressBook) \
.filter(AddressBook.city == "boston") \
.filter((AddressBook.lastname == 'bulger') | (AddressBook.firstname == 'whitey'))
l'opérateur or_ peut être utile en cas de nombre inconnu de composants de requête OR.
Par exemple, supposons que nous créons un service REST avec peu de filtres facultatifs, qui devrait renvoyer un enregistrement si l'un des filtres renvoie la valeur true. D'un autre côté, si le paramètre n'était pas défini dans une requête, notre requête ne devrait pas changer. Sans or_ function, nous devons faire quelque chose comme ceci:
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))
Avec or_ function, il peut être réécrit pour:
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))
Cela a été vraiment utile. Voici mon implémentation pour toute table donnée:
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)