2009-05-28 14 views
6

Sadece bir CRM uygulamasından sqlalchemy ile oldukça kötü bir şemaya göz attım. Tüm tabloların üzerinde silinmiş bir sütun var ve tüm bu varlıkları ve silinmiş olarak işaretlenen ilişkileri otomatik olarak filtrelemek istedim.SQLAlchemy sorgularını otomatik olarak filtrelemenin doğru yolu?


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 

Ve böyle kullanılır:

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 e-posta ve onlar konum diğer Modülleri arasındaki katılmak tabloya eşlenmiş sınıftır İşte ben ile geldi ne ile ilgili.

İşte eşlemleyıcı bir örnek: Bu ben tüm silinmiş İletişim filtre ettik istediğini bana verir

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 

. Ben Dini kompleks sınıfının iç elemanlar buralarda dolanıyor gerçekten mutlu değilim,

  1. Bunu yapmak için daha iyi bir yolu var mı ... Ancak - Ben de haritacılarımızdan içinde dynamic_loader için query_class argüman olarak kullanabilirsiniz Benimki gibi Sorgu gibi.
  2. Bunu paylaşabilecekleri başka bir şekilde kim çözdü?

cevap

7

Bir seçimle eşleştirebilirsiniz. Şunun gibi:

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

Çok hoş, bunu bilmiyordum! –

+0

Sadece bunu (farklı bir masada) yapmaya çalıştım ve işe yaramadı. Ben var: TypeError: 'Tablo' nesnesi yinelenebilir değil Herhangi bir fikri neden? –

+0

Benim kötü, seçmek için ilk parametre sütunlar/tablo benzeri nesnelerin bir listesidir, bu yüzden email_join bir listede olmalıdır. Onu tamir edeceğim. –

0

Ben silinen elemanları filtrelemek bu tablolar için görünümler oluşturmak mümkün olsaydı görmeye düşünün ve sonra yerine altta yatan tablonun o görünüme doğrudan harita mümkün olabilir, en azından sorgulama işlemleri için. Ancak bunu kendim hiç denemedim!