您好,我想使用 joinload 对我的查询进行过滤。但我似乎无法让它发挥作用。以下是我的示例查询
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 行,这比我预期的要多得多
它不起作用的原因是joinedload
(以及所有其他关系加载技术)应该是完全透明的。也就是说有一个joinedload
除了导致关系被填充之外,您的查询中不应以任何其他方式影响它。你应该阅读《加入热切加载的禅宗》 https://docs.sqlalchemy.org/en/20/orm/queryguide/relationships.html#the-zen-of-joined-eager-loading,开头为:
由于加入的急切加载似乎与使用有很多相似之处Query.join()
,它经常会产生关于何时以及如何使用它的混乱。理解两者之间的区别至关重要Query.join()
用于改变查询的结果,joinedload()
我们竭尽全力不改变查询的结果,而是隐藏渲染连接的效果,只允许相关对象出现。
技巧之一是对不可用的连接表使用别名。然后,您的查询最终会在“工作”和“用户”之间执行隐式交叉联接,从而产生额外的行。因此,为了过滤连接表,请使用Query.join() http://docs.sqlalchemy.org/en/latest/orm/query.html#sqlalchemy.orm.query.Query.join:
session.query(Work).\
join(Work.company_users).\
join(CompanyUser.user).\
filter(Work.id == 1).\
filter(User.first_name == 'The name').\
all()
如果您还需要立即加载,您可以指示查询它已经包含与contains_eager() http://docs.sqlalchemy.org/en/latest/orm/loading_relationships.html#sqlalchemy.orm.contains_eager:
session.query(Work).\
join(Work.company_users).\
join(CompanyUser.user).\
options(contains_eager(Work.company_users).
contains_eager(CompanyUser.user)).\
filter(Work.id == 1).\
filter(User.first_name == 'The name').\
all()
注意链式调用contains_eager()
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)