私はちょうどsqlalchemyを持つCRMアプリケーションからかなり厄介なスキーマをイントロスペクトしました。すべてのテーブルに削除された列があり、それらのエンティティとリレーションシップのすべてを自動的にフィルタリングして、削除済みとしてフラグを付けたかったのです。ここに私が思い付いたものです: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
そして、それはこのように使われています:
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は、電子メールや、彼らがしている他のモジュール間の結合テーブルにマップされていますクラスでありますに関連する。
は、ここでは、マッパーの例です:これは私がすべて削除された連絡先を除外したことで欲しいものを私に与え
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
。私も自分のマッパーでdynamic_loaderするQUERY_CLASS引数としてこれを使用することができます - しかし...
- がこれを行うには良い方法がありますが、私はcompicatedクラスの内部でチャンスをうかがっには本当に満足していません私のような質問があります。
- 誰かが共有できる別の方法でこれを解決しましたか?
非常にいいです、私はそれについて知りませんでした! –
私はこれを(別のテーブルで)しようとしましたが、うまくいかなかったのです。私は得ました: TypeError: 'テーブル'オブジェクトは反復可能ではありません 何が良いのでしょうか? –
私の悪い、選択する最初のパラメータは、オブジェクトのような列/テーブルのリストですので、email_joinはリストになければなりません。私はそれを修正します。 –