编辑:我认为SQL的WHERE条件中的顺序很重要,因此也是我要求解决该问题的原因。因此,我得到了答案。
我正在尝试在sqlalchemy模型中设置默认查询过滤器,该过滤器在每次调用查询时执行。
但是问题在于它在查询的末尾添加了过滤器,这破坏了我的SQL。
是否可以使其在查询中首先过滤?
我遵循以下食谱: https://github.com/sqlalchemy/sqlalchemy/wiki/FilteredQuery
食谱中的骨架:
# see the linked web page, for full code
@event.listens_for(Query, "before_compile", retval=True)
def before_compile(query):
for ent in query.column_descriptions:
entity = ent['entity']
if entity is None:
continue
insp = inspect(ent['entity'])
mapper = getattr(insp, 'mapper', None)
if mapper and issubclass(mapper.class_, HasPrivate):
query = query.enable_assertions(False).filter(
ent['entity'].public == True)
return query
# this is my filter
query = query.enable_assertions(False).filter(
ent['entity'].id != ent['entity'].other_id)
ent['entity'].id != ent['entity'].other_id
放在我的SQL查询的末尾。
答案 0 :(得分:1)
我认为在将过滤器添加到查询时应添加break
语句,否则可能会多次在相同条件下进行过滤。
看看filter方法的internals,我看到以下代码要执行以获取条件或条件列表:
for criterion in list(criterion):
criterion = expression._expression_literal_as_text(criterion)
criterion = self._adapt_clause(criterion, True, True)
if self._criterion is not None:
self._criterion = self._criterion & criterion
else:
self._criterion = criterion
这意味着您可以使用以下代码添加条件:
@event.listens_for(Query, "before_compile", retval=True)
def before_compile(query):
criterion = query._adapt_clause(criterion, True, True)
for ent in query.column_descriptions:
entity = ent['entity']
if entity is None:
continue
insp = inspect(ent['entity'])
mapper = getattr(insp, 'mapper', None)
if mapper and issubclass(mapper.class_, HasPrivate):
if query._criterion is not None:
query._criterion = criterion & query._criterion
else:
query._criterion = criterion
break
return query