Ho appena introspettato uno schema piuttosto sgradevole da un'app CRM con sqlalchemy. Tutte le tabelle hanno una colonna cancellata e volevo filtrare automaticamente tutte le entità e le relazioni contrassegnate come cancellate. Ecco quello che mi si avvicinò con:Il modo giusto per filtrare automaticamente le query SQLAlchemy?
class CustomizableQuery(Query):
"""An overridden sqlalchemy.orm.query.Query to filter entities
Filters itself by BinaryExpressions
found in :attr:`CONDITIONS`
"""
CONDITIONS = []
def __init__(self, mapper, session=None):
super(CustomizableQuery, self).__init__(mapper, session)
for cond in self.CONDITIONS:
self._add_criterion(cond)
def _add_criterion(self, criterion):
criterion = self._adapt_clause(criterion, False, True)
if self._criterion is not None:
self._criterion = self._criterion & criterion
else:
self._criterion = criterion
ed è utilizzato in questo modo:
class UndeletedContactQuery(CustomizableQuery):
CONDITIONS = [contacts.c.deleted != True]
def by_email(self, email_address):
return EmailInfo.query.by_module_and_address('Contacts', email_address).contact
def by_username(self, uname):
return self.filter_by(twod_username_c=uname).one()
class Contact(object):
query = session.query_property(UndeletedContactQuery)
Contact.query.by_email('[email protected]')
EmailInfo è la classe che ha mappato alla tabella di raccordo tra e-mail e gli altri moduli che sono collegato a.
Ecco un esempio di un mapper:
contacts_map = mapper(Contact, join(contacts, contacts_cstm), {
'_emails': dynamic_loader(EmailInfo,
foreign_keys=[email_join.c.bean_id],
primaryjoin=contacts.c.id==email_join.c.bean_id,
query_class=EmailInfoQuery),
})
class EmailInfoQuery(CustomizableQuery):
CONDITIONS = [email_join.c.deleted != True]
# More methods here
Questo mi dà quello che voglio in che ho filtrato tutti i contatti eliminati. Posso anche usare questo come argomento query_class a dynamic_loader nei miei mapper - Tuttavia ...
- c'è un modo migliore per fare questo, io non sono molto contento di frugare con la struttura interna di una classe compicated come Query come sono.
- Qualcuno ha risolto questo in un modo diverso che possono condividere?
Molto bello, non lo sapevo! –
Ho appena provato a farlo (su una tabella diversa) e non ha funzionato. Ho ricevuto: TypeError: l'oggetto 'Table' non è iterable Qualche idea sul perché? –
Il mio male, il primo parametro da selezionare è un elenco di colonne/oggetti di tipo tabella, quindi email_join dovrebbe essere in un elenco. Lo aggiusterò. –