我刚刚使用sqlalchemy从一个CRM应用程序中审查了一个相当恶劣的模式。 所有表格都有一个已删除列,我想自动过滤所有被标记为已删除的实体和关系。以下是我想出来的解决方案:
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
以下是它的使用方法:
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('someone@some.com')
EmailInfo是映射到电子邮件和其他相关模块之间连接表的类。
以下是一个映射器示例:
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
这样做可以过滤掉所有已删除的联系人,达到了我的目的。我还可以将其作为动态加载器中映射器的查询类参数 - 但是...
- 有没有更好的方法来实现这一点?我不太喜欢像我这样钻研Query这样复杂的类的内部。
- 有没有其他人用不同的方式解决了这个问题,可以分享一下吗?