Ich habe gerade ein ziemlich unangenehmes Schema aus einer CRM-App mit sqlalchemy introspected. Alle Tabellen haben eine gelöschte Spalte und ich wollte alle diese Entitäten und Beziehungen, die als gelöscht gekennzeichnet sind, automatisch filtern. Hier ist, was ich kam mit:Der richtige Weg zum automatischen Filtern von SQLAlchemy-Abfragen?
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
Und es ist so benutzten:
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 ist die Klasse, die zwischen E-Mails und die anderen Module der Join-Tabelle zugeordnet ist, dass sie bezüglich.
Hier ist ein Beispiel für einen 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
Das gibt mir, was ich in möchten, dass ich alle gelöschten Kontakte herausgefiltert haben. Ich kann auch diese als QUERY_CLASS Argument in meinem Mapper dynamic_loader - aber ...
- Gibt es einen besseren Weg, dies zu tun, ich bin nicht wirklich glücklich mit stocherte mit dem Interna einer umfangreichen und fremden Klasse wie Abfrage wie ich bin.
- Hat jemand das auf eine andere Weise gelöst, die sie teilen können?
Sehr nett, wusste ich nicht darüber! –
Ich habe gerade versucht, dies zu tun (auf einer anderen Tabelle) und es hat nicht funktioniert. Ich habe: TypeError: 'Table' Objekt ist nicht iterierbar Irgendeine Idee warum? –
Mein Fehler, der erste zu wählende Parameter ist eine Liste mit spalten-/tabellenähnlichen Objekten, daher sollte email_join in einer Liste sein. Ich werde es reparieren. –