Właśnie przeszedłem introspekcję dość nieprzyjemnego schematu z aplikacji CRM z sqlalchemy. Wszystkie tabele mają na nich usuniętą kolumnę i chciałem automatycznie filtrować wszystkie te encje i relacje oflagowane jako usunięte. Oto co wymyśliłem:Właściwy sposób automatycznego filtrowania zapytań 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
I jest używany tak:
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 jest klasa, który jest mapowany do tabeli sprzężenia między e-maili i innych modułów, którymi są związany z.
Oto przykład odwzorowującym:
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
Daje mi to, co chcę, że mam odfiltrowane wszystkie usunięte kontakty. Mogę też użyć tego jako argumentu query_class do dynamic_loader w moich mappers - Jednak ...
- Czy istnieje lepszy sposób to zrobić, nie jestem naprawdę szczęśliwy z wywiercenie z wewnętrznych o compicated klasie jak Query, jak ja.
- Czy ktoś rozwiązał to w inny sposób, niż może to udostępnić?
Bardzo miło, nie wiedziałem o tym! –
Po prostu próbowałem to zrobić (na innym stole) i to nie zadziałało. Mam: TypeError: Obiekt "Table" nie jest iterable Czy jest jakiś pomysł? –
Mój zły, pierwszym parametrem do wyboru jest lista kolumn/tabel podobnych do obiektów, więc email_join powinien znajdować się na liście. Naprawię to. –