Je viens d'introspecter un schéma assez méchant d'une application CRM avec sqlalchemy. Tous les tableaux ont une colonne supprimée sur eux et je voulais filtrer automatiquement toutes ces entités et les relations marquées comme supprimées. Voici ce que je suis venu avec:La bonne façon de filtrer automatiquement les requêtes 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
Et il est utilisé comme ceci:
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 est la classe qui est mis en correspondance avec la table de jointure entre les e-mails et les autres modules qu'ils relatif à.
Voici un exemple d'un mappeur:
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
Cela me donne ce que je veux dans ce que j'ai filtré tous les contacts supprimés. Je peux aussi l'utiliser comme argument QUERY_CLASS à dynamic_loader dans mes cartographes - Mais ...
- est-il une meilleure façon de faire, je ne suis pas vraiment content de farfouillé avec les internes d'une classe compicated comme interroger comme je suis.
- Est-ce que quelqu'un a résolu cela d'une manière différente qu'ils peuvent partager?
Très bien, je ne savais pas à ce sujet! –
J'ai juste essayé de faire ceci (sur une table différente) et cela n'a pas fonctionné. J'ai: TypeError: l'objet 'Table' n'est pas itérable Une idée pourquoi? –
Mon mauvais, le premier paramètre à sélectionner est une liste de colonnes/objets de type table, donc email_join devrait être dans une liste. Je le réparerai. –