【问题标题】:SQLAlchemy - only one result being returned when count() says there are moreSQLAlchemy - 当 count() 说还有更多时,只返回一个结果
【发布时间】:2011-10-19 11:52:26
【问题描述】:

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

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

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

【问题讨论】:

    标签: python database select sqlalchemy


    【解决方案1】:

    Query 对象在被要求遍历表示像 TestSet 这样的实体的结果时,会根据对象身份对结果行执行唯一性,这样如果查询要返回 100 行,每行都具有相同的 @987654323 @主键,你只会得到一个结果对象。这种行为起源于Query 的“急切加入”功能,在这种情况下,通常会收到许多结果行,每个结果行都具有相同的主标识,但也包含相关行的不同辅助标识根据每个主要身份填充到一个集合中 - 在这种非常常见的情况下,只需要主要身份的一个实例。

    然后让我们考虑一下distinct() 做了什么。假设您对 4M 对象的查询返回 id=1 的 1000 行、id=2 的 1000 行等。limit(100) 的查询命中 id=1 的前 100 行,Query uniquifies,你得到一个结果对象返回,因为它们都是 id=1。但是使用distinct(),我们突然得到了 100 行具有不同身份的行,即“id=1”、“id=2”、“id=3”。 Query 然后将这些行中的每一行分配给身份映射中的一个新 TestSet 对象,然后您将返回 100 行。

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

    【讨论】:

    • 救命稻草解释(被困在同一个问题很长一段时间)。我的错误是我在表声明期间将错误的列声明为“primary_key”。因此,ORM 将我的结果行唯一地合并(分组)到只有 1 行。
    猜你喜欢
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-05
    • 1970-01-01
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多