8

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

これにより、削除されたすべての連絡先を除外したという点で、必要なものが得られます。これを、マッパーで dynamic_loader への query_class 引数として使用することもできます - ただし...

  1. これを行うためのより良い方法はありますか?私は Query のような複雑なクラスの内部をいじることに本当に満足していません。
  2. 共有できる別の方法でこれを解決した人はいますか?
4

2 に答える 2

7

選択にマップできます。このような:

mapper(EmailInfo, select([email_join], email_join.c.deleted == False))
于 2009-05-28T13:11:18.677 に答える
0

削除された要素を除外するこれらのテーブルのビューを作成できるかどうかを検討したいと思います。そうすれば、少なくともクエリ操作のために、基になるテーブルの代わりにそのビューに直接マップできる可能性があります。しかし、私はこれを自分で試したことはありません!

于 2009-05-29T11:22:27.307 に答える