2009-05-28 6 views
6

Ich habe gerade ein ziemlich unangenehmes Schema aus einer CRM-App mit sqlalchemy introspected. Alle Tabellen haben eine gelöschte Spalte und ich wollte alle diese Entitäten und Beziehungen, die als gelöscht gekennzeichnet sind, automatisch filtern. Hier ist, was ich kam mit:Der richtige Weg zum automatischen Filtern von SQLAlchemy-Abfragen?


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 

Und es ist so benutzten:

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 ist die Klasse, die zwischen E-Mails und die anderen Module der Join-Tabelle zugeordnet ist, dass sie bezüglich.

Hier ist ein Beispiel für einen Mapper:

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 

Das gibt mir, was ich in möchten, dass ich alle gelöschten Kontakte herausgefiltert haben. Ich kann auch diese als QUERY_CLASS Argument in meinem Mapper dynamic_loader - aber ...

  1. Gibt es einen besseren Weg, dies zu tun, ich bin nicht wirklich glücklich mit stocherte mit dem Interna einer umfangreichen und fremden Klasse wie Abfrage wie ich bin.
  2. Hat jemand das auf eine andere Weise gelöst, die sie teilen können?

Antwort

7

Sie können eine Auswahl zuordnen. Wie folgt aus:

mapper(EmailInfo, select([email_join], email_join.c.deleted == False)) 
+0

Sehr nett, wusste ich nicht darüber! –

+0

Ich habe gerade versucht, dies zu tun (auf einer anderen Tabelle) und es hat nicht funktioniert. Ich habe: TypeError: 'Table' Objekt ist nicht iterierbar Irgendeine Idee warum? –

+0

Mein Fehler, der erste zu wählende Parameter ist eine Liste mit spalten-/tabellenähnlichen Objekten, daher sollte email_join in einer Liste sein. Ich werde es reparieren. –

0

Ich würde prüfen, zu sehen, ob es möglich war, Ansichten für diese Tabellen zu erstellen, die die gelöschten Elemente herauszufiltern, und dann könnten Sie in der Lage sein, direkt anstelle der zugrunde liegenden Tabelle zu dieser Ansicht abzubilden, zumindest für die Abfrage von Operationen. Allerdings habe ich das selbst nie ausprobiert!