Acabo de introspectar un esquema bastante desagradable de una aplicación de CRM con sqlalchemy. Todas las tablas tienen una columna eliminada y quería filtrar automáticamente todas las entidades y relaciones marcadas como eliminadas. Esto es lo que ocurrió:¿La forma correcta de filtrar automáticamente las consultas de 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
y se usa así:
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 es la clase que se asigna a la tabla de unión entre los correos electrónicos y los otros módulos que están relacionado con.
He aquí un ejemplo de un mapeador:
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
Esto me da lo que quiero en que yo que cumplan con todos los contactos eliminados. También puede utilizar esto como el argumento query_class a dynamic_loader en mis mapeadores - Sin embargo ...
- ¿Hay una mejor manera de hacer esto, no estoy muy contento con hurgando con el funcionamiento interno de una clase compicated como Query como soy.
- ¿Alguien ha resuelto esto de una manera diferente que puedan compartir?
¡Muy bien, no sabía de eso! –
Acabo de intentar hacer esto (en una tabla diferente) y no funcionó. Tengo: TypeError: el objeto 'Tabla' no es iterable ¿Alguna idea de por qué? –
Malo, el primer parámetro para seleccionar es una lista de objetos similares a columnas/tabla, por lo que email_join debe estar en una lista. Lo arreglaré. –