Если я вас правильно понял, вам нужно, чтобы все неактивные объекты стали невидимыми для ваших запросов.Следующий класс отфильтрует все объекты модели с атрибутом active
, установленным на False
, включая те, к которым осуществляется доступ через отношения:
from sqlalchemy.orm import Query
from sqlalchemy.orm.util import _class_to_mapper
class QueryActive(Query):
def __init__(self, entities, *args, **kwargs):
Query.__init__(self, entities, *args, **kwargs)
query = self
for entity in entities:
if hasattr(entity, 'parententity'):
entity = entity.parententity
cls = _class_to_mapper(entity).class_
if hasattr(cls, 'active'):
query = query.filter(cls.active==True)
self._criterion = query._criterion
def get(self, ident):
# Use default implementation when there is no condition
if not self._criterion:
return Query.get(self, ident)
# Copied from Query implementation with some changes.
if hasattr(ident, '__composite_values__'):
ident = ident.__composite_values__()
mapper = self._only_mapper_zero(
"get() can only be used against a single mapped class.")
key = mapper.identity_key_from_primary_key(ident)
if ident is None:
if key is not None:
ident = key[1]
else:
from sqlalchemy import util
ident = util.to_list(ident)
if ident is not None:
columns = list(mapper.primary_key)
if len(columns)!=len(ident):
raise TypeError("Number of values doesn't match number "
'of columns in primary key')
params = {}
for column, value in zip(columns, ident):
params[column.key] = value
return self.filter_by(**params).first()
Чтобы использовать его, необходимо создать отдельный объект сеанса:
session_active = sessionmaker(bind=engine, query_cls=QueryActive)()
Такой подход имеет ограничения и не подходит для некоторых сложных запросов, но подходит для большинства проектов.