正确的SqlAlchemy查询使用contains\u
我有一个问题,我已经找到了一个有效的解决方案。我不确定我是否正确执行了查询,我希望能找到答案。各表如下: 查询是:正确的SqlAlchemy查询使用contains\u,sqlalchemy,Sqlalchemy,我有一个问题,我已经找到了一个有效的解决方案。我不确定我是否正确执行了查询,我希望能找到答案。各表如下: 查询是: q = session.query(Person).outerjoin(PetOwner).join(Animal).options(contains_eager("petowner_set"), contains_eager("petowner_set.animal")) 人与宠物主人之间有关系 如果从person到petowner的连接和从petowner到animal的连
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\u eager
调用
这是实现这一目标的正确方法吗?简短回答:据我所知,你应该使用
外部连接
,除非你不想看到没有动物的人
首先,让我们看一看JOIN
s:
two-internal
:在这种情况下,查询结果将只返回至少有一只动物的那些Person
s(假设任何PetOwner.animal
都不可为空)
外部用于PetOwner,内部用于Animal
:同上(再次假设任何PetOwner.Animal
都不可为空)
两个外部
:查询结果将返回所有个人
s,无论他们是否拥有动物
那么,包含了什么呢?据报道,
。。。将向查询指示应急切地从查询中当前的列加载给定属性
这意味着,当您访问Person.petowner\u set
时,不需要额外的数据库查询,因为SA将从原始查询中加载关系。这绝对不会影响连接的工作方式,只会影响关系的加载。这只是一个数据加载优化。我认为唯一的区别是您应该将调用链接到contains\u eager
,如下所示:
q = (session.query(Person)
.outerjoin(PetOwner)
.join(Animal)
.options(
contains_eager("petowner_set").contains_eager("petowner_set.animal")
)
)
请参阅:我应该在问题中详细说明。我正在寻找执行数据加载的正确方法。我需要查询只调用一次,并且仍然能够访问petowner_集和每个petowner的宠物。在不加载数据的情况下执行此操作相当简单,但随后会变成一个n+1查询。我不确定我是否正确使用了contains\u eager。我最初尝试了outerjoin,但我需要一个outerjoin和一个innerjoin,正如我在问题中的查询一样。为什么需要innerjoin
?嘘,我的意思是我最初尝试了joinedload\u all。我的问题是:joinedload_all(“petowner_set.animal”),它可以工作,但使它们都在外面。至于为什么我需要一个内部连接,fk pet on petowner是一个必填字段。没有宠物,宠物主人就无法生存。所以内部连接只是逻辑上的。我不是最擅长优化的,但我认为外层连接效率较低。是的,innerjoin
是合乎逻辑的,但前提是你要孤立地查看PetOwner->Pet
。但是,此内部连接将过滤掉没有任何动物的人。如果这是您想要的-很好,如果不是-您需要两个连接都是外部的
。