2011-08-03 54 views
3

我遇到了一個非常大的結果集只返回一行的問題。SQLAlchemy - 當count()表示還有更多的時候,只返回一個結果

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個結果。這裏發生了什麼?

回答

9

Query對象,當被問及通過代表像TestSet實體結果進行迭代,執行uniquing基於對象標識的結果行,因此,如果查詢中來回報每100行與同TestSet主鍵, '只返回一個結果對象。這種行爲起源於Query的「渴望加入」特徵,在這種情況下,許多結果行通常都以相同的主要標識接收,但也包含將要填充到的相關行的不同次要標識每個主要身份的集合 - 在這種常見的情況下,只有一個主要身份的實例是可取的。

讓我們再來考慮一下distinct()是做什麼的。假設你對4M對象的查詢返回1000行id = 1,1000行id = 2,等等。限制(100)的查詢命中id = 1的前100行,得到唯一的結果,你得到一個結果對象,因爲它們都是id = 1。但是對於distinct(),突然我們得到具有不同身份的100行,即「id = 1」,「id = 2」,「id = 3」。 Query然後將這些行中的每一行分配給標識映射中的新對象TestSet,並返回100行。

在你的Engine上設置echo='debug'暫時會顯示正在發出的SQL以及返回的結果行。當你看到許多結果行都具有相同的主鍵時,當被要求返回完整實體時,你知道Query將把所有這些冗餘標識唯一地映射到表示每行的單個對象。

相關問題