嗨,我想用joinedload对我的查询做一个过滤器。但是我似乎不能让它工作。下面是我的示例查询
result = (
session.query(Work).
options(
joinedload(Work.company_users).
joinedload(CompanyUser.user)
).
filter(Work.id == 1).
filter(User.first_name == 'The name'). <<--- I can't get this to work.
all()
)
运行此查询时,返回的行比我预期的多。真实的结果应仅返回8行。但在执行此查询时,返回234行,比我预期的多很多
2条答案
按热度按时间insrf1ej1#
它不起作用的原因是
joinedload
(以及所有其他关系加载技术)应该是完全透明的。也就是说,在查询中使用joinedload
不应该以任何其他方式影响它,而只是导致填充关系。您应该阅读“连接的渴望加载的禅宗”,它的开头是:由于联合急切加载看起来与
Query.join()
的使用有许多相似之处,它经常会在何时以及如何使用它方面产生混淆。理解Query.join()
用于更改查询结果,而joinedload()
则不遗余力地不更改查询结果这一区别是至关重要的。而是隐藏所呈现的联接的效果以仅允许相关对象存在。其中一个技巧是为不可用的连接表使用别名。然后,您的查询将在Work和User之间执行隐式交叉连接,从而导致额外的行。因此,为了针对连接表进行过滤,请使用
Query.join()
:如果您还需要将eagerloads放在适当的位置,您可以指示Query它已经包含了与
contains_eager()
的连接:注意对
contains_eager()
的链式调用。bvn4nwqk2#
好的,我明白了。只是为了那些可能解决同样问题的人,我所做的是将joinedload替换为contains_eager,并添加了一个join。下面是修改代码