2013-04-10 4 views
17

Sorgu nesnesine özel yöntemler oluşturmanın bir yolu var mı, böylece böyle bir şey yapabilirsiniz? all_active() esasen .filter(User.is_active == True)SQLAlchemy - sorgu nesnesine özel yöntemler ekleyebilir misiniz?

Ve bunun kapalı filtreleyemez olan

User.query.all_active() 

?

User.query.all_active().filter(User.age == 30) 
+0

acaba bu diğer [soru/cevap] içinde herhangi bir şey (http://stackoverflow.com/questions/7604967/ sqlalchemy-build-query-filtre-dinamik-in-dict) bunun için herhangi bir kullanım olabilir? (Özel bir yöntemden daha az ... ve özel bir dinamik filtrenin daha fazlası.) – summea

cevap

33

Kendi yöntemleri eklemek üssü Query sınıf alt sınıf:

from sqlalchemy.orm import Query 

class MyQuery(Query): 

    def all_active(self): 
    return self.filter(User.is_active == True) 

Eğer oturumu (docs here) oluştururken Daha sonra, bu yeni sorgu sınıfını kullanmak SQLAlchemy söyle. Kodunuzdaki itibaren Flask-SQLAlchemy kullanıyor olabilir gibi görünüyor, bu nedenle aşağıdaki gibi yapardı:

db = SQLAlchemy(session_options={'query_cls': MyQuery}) 

Aksi takdirde sessionmaker doğrudan argüman geçerdi:

sessionmaker(bind=engine, query_cls=MyQuery) 

sağ itibariyle şimdi, bu yeni sorgu nesnesi bu ilginç değil çünkü biz User sınıfını bu yöntemde kodladık, bu yüzden başka bir şey için çalışmayacak. Daha iyi bir uygulama, hangi filtrenin uygulanacağını belirlemek için sorgunun temel sınıfını kullanır. Bu biraz zor ama aynı zamanda yapılabilir:

class MyOtherQuery(Query): 

    def _get_models(self): 
    """Returns the query's underlying model classes.""" 
    if hasattr(query, 'attr'): 
     # we are dealing with a subquery 
     return [query.attr.target_mapper] 
    else: 
     return [ 
     d['expr'].class_ 
     for d in query.column_descriptions 
     if isinstance(d['expr'], Mapper) 
     ] 

    def all_active(self): 
    model_class = self._get_models()[0] 
    return self.filter(model_class.is_active == True) 

Son olarak, bu yeni sorgu sınıfı dinamik ilişkiler tarafından kullanılmayacaktır (eğer varsa). Eğer ilişki oluştururken argüman olarak geçebilir, bu da onu kullanmasına izin vermek için:

users = relationship(..., query_class=MyOtherQuery) 
+0

Bu benim için çalışmıyor. https://gist.github.com/nickretallack/76bcd65cc0305abcd33b –

+1

@NickRetallack Bir BaseModel sınıfı oluşturma ve query_class sınıfı özniteliğini bildirme konusunda bazı başarılar elde ettim. Ancak, bu sorun gibi görünüyor: https://github.com/mitsuhiko/flask-sqlalchemy/blob/fe67c633f2e6d66a01a1670e5fc6649506358d20/flask_sqlalchemy/__init__.py#L737 – justanr

+0

Yani bir oturumun yalnızca bir sorgu sınıfı ile çalışabileceğini söylüyorsunuz. Daha iyisini yapabilir miyiz? ve aynı oturumu dinamik olarak sorgu sınıfını seçmek için izin verilsin mi? Farklı tabloların farklı sorgu sınıflarına sahip olabileceğini kastediyorum, ancak bunları aynı oturumda kullanmak isteyebilirim (örneğin, bunları bir işlemde kullanırken). – Mahdi