SQLAlchemy - 当count()表示还有更多时,只返回一个结果

时间:2011-08-03 21:22:24

标签: python database select sqlalchemy

我遇到一个非常大的结果集只有返回一行的问题。

Session.query(TestSet).join(Instance).count()
>> 4283878
Session.query(TestSet).join(Instance).offset(0).limit(100).count()
>> 100
Session.query(TestSet).join(Instance).offset(0).limit(100).all()
>> [<model.testset.TestSet object at 0x043EC2F0>]

也就是说,all只返回我模型的一个实例,而不是100.现在,对于更奇怪的东西:

len(Session.query(TestSet).join(Instance).offset(0).limit(100).distinct().all())
>> 100

因此,如果我在distinct之前添加all,我会收到所有100个结果。这是怎么回事?

1 个答案:

答案 0 :(得分:12)

Query对象被要求迭代表示像TestSet这样的实体的结果时,会根据对象标识对结果行进行统一,这样如果查询要返回每行100行,相同的TestSet主键,您只能获得一个结果对象。这种行为起源于&#34;渴望加入&#34; Query的特征,通常情况是,每个具有相同主要身份的许多结果行都被接收,但是还包含要填充的相关行的不同的次要身份。在每个主要身份的集合中 - 在这种非常常见的情况下,只需要一个主要身份的实例。

然后考虑一下distinct()的作用。假设您对4M对象的查询返回1000行,其中id = 1,1000行,id = 2,等等。带有限制(100)的查询命中前100行,id = 1,Query unquifies,然后你得到返回一个结果对象,因为它们都是id = 1。但是对于distinct(),我们突然得到100行具有不同的身份,即&#34; id = 1&#34;,&#34; id = 2&#34;,&#34; id = 3&#34 ;。然后Query将每个行分配给身份映射中的新TestSet对象,然后返回100行。

暂时在echo='debug'上设置Engine将显示正在发出的SQL以及返回的结果行。当您看到许多结果行都具有相同的主键时,您知道当被要求返回完整实体时Query将使所有这些冗余标识唯一,直到每行所代表的单个对象。