Można podklasy podstawy Query
klasę, aby dodać swoje własne metody:
from sqlalchemy.orm import Query
class MyQuery(Query):
def all_active(self):
return self.filter(User.is_active == True)
następnie poinformować SQLAlchemy aby skorzystać z tej nowej klasy zapytania podczas tworzenia sesji (docs here). Z kodu wygląda być może używasz skrzynkowego SQLAlchemy, więc można to zrobić w następujący sposób:
db = SQLAlchemy(session_options={'query_cls': MyQuery})
Inaczej byś przekazać argument bezpośrednio do sessionmaker
:
sessionmaker(bind=engine, query_cls=MyQuery)
z mocy prawa teraz ten nowy obiekt zapytania nie jest interesujący, ponieważ w metodzie zakodowano klasę User
, więc nie będzie ona działała na nic innego. Lepsza implementacja użyłaby podstawowej klasy zapytania do określenia, który filtr zastosować. Jest to nieco skomplikowane, ale można to zrobić także:
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)
Wreszcie, ta nowa klasa zapytanie nie będzie używany przez dynamicznych relacji (jeśli występują). Niech ci również użyć go, można przekazać go jako argument podczas tworzenia relacji:
users = relationship(..., query_class=MyOtherQuery)
Zastanawiam się, czy coś w tym drugim [Pytanie/odpowiedź] (http://stackoverflow.com/questions/7604967/ sqlalchemy-build-query-filter-dynamically-from-dict) może być w tym celu przydatna? (Jest to jednak mniej niestandardowa metoda ... i bardziej niestandardowy filtr dynamiczny). – summea