我有一个查询,我找到了一个有效的解决方案。我不确定我是否正确执行查询,我希望能找到答案。表格如下:
查询是:
q = session.query(Person).outerjoin(PetOwner).join(Animal).options(contains_eager("petowner_set"), contains_eager("petowner_set.animal"))
将人们与宠物主人联系起来是有关系的。
如果从person
到petowner
的加入以及从petowner
到animal
的加入都是内部联接或两个外部联接,那将很容易。但是,从person
到petowner
的联接是外联接,从petowner
到animal
的联接是内联接。为此,我在选项中添加了两个contains_eager
次调用。
这是完成此任务的正确方法吗?
答案 0 :(得分:4)
简答: 从我所看到的情况来看,您应该使用outerjoin
两者,除非您不希望看到Persons
没有动物
首先,让我们看看JOIN
s:
both INNER
:在这种情况下,您的查询结果将返回仅那些至少有一只动物的Person
(假设任何PetOwner.animal
是不可空的)OUTER for PetOwner, INNER for Animal
:与上述相同(同样,假设任何PetOwner.animal
不可为空)both OUTER
:您的查询结果将返回所有 Person
s,无论他们是否拥有Animal
那么,contains_eager
做了什么?根据{{3}},
...将向查询指出应该从当前查询中的列急切加载给定属性。
这意味着当您访问Person.petowner_set
时,不需要额外的数据库查询,因为SA将从原始查询加载关系。这绝对不会影响JOINs
的工作方式,只会影响关系的加载。这只是一个数据加载优化。
答案 1 :(得分:1)
我认为唯一的区别是您应该将呼叫链接到contains_eager
,如下所示:
q = (session.query(Person)
.outerjoin(PetOwner)
.join(Animal)
.options(
contains_eager("petowner_set").contains_eager("petowner_set.animal")
)
)
请参阅:https://docs.sqlalchemy.org/en/latest/orm/loading_relationships.html#controlling-loading-via-options