4

我有一个查询,我找到了一个可行的解决方案。我不确定我是否正确执行了查询,我希望能找到答案。表格如下所示:

所有者

查询是:

q = session.query(Person).outerjoin(PetOwner).join(Animal).options(contains_eager("petowner_set"), contains_eager("petowner_set.animal"))

将其与宠物主人联系起来的人有关系。

person如果连接 from topetowner和 join from petownertoanimal都是内连接或外连接,这将很容易。但是,从personto连接petowner是外连接,从petownerto连接animal是内连接。为此,我向contains_eager选项添加了两个调用。

这是完成此任务的正确方法吗?

4

2 回答 2

4

简短回答: 据我所知,您应该同时使用outerjoin两者,除非您不想看到Persons谁没有动物

首先,让我们看一下JOINs:

  • both INNER:在这种情况下,您的查询结果将返回那些Person至少有一只动物的 s(假设 anyPetOwner.animal不可为空)
  • OUTER for PetOwner, INNER for Animal:与上面相同(再次假设 anyPetOwner.animal不可为空)
  • both OUTER: 你的查询结果将返回所有 Persons 而不管他们是否Animal拥有

那么,怎么contains_eager办?根据文件

... 将向查询指示应该从当前查询中的列中急切地加载给定的属性。

这意味着当您访问 时Person.petowner_set,不需要额外的数据库查询,因为 SA 将从您的原始查询加载关系。这绝对不会影响您的JOINs工作方式,只会影响关系的加载。这只是一个数据加载优化。

于 2012-07-20T09:15:04.787 回答
2

我认为唯一的区别是您应该将调用链接到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

于 2018-11-14T07:34:01.540 回答