2013-06-20 14 views
21

的SQLAlchemy的Query.distinct方法不一致的行爲:返回在SQLAlchemy的不同行使用SQLite

>>> [tag.name for tag in session.query(Tag).all()] 
[u'Male', u'Male', u'Ninja', u'Pirate'] 
>>> session.query(Tag).distinct(Tag.name).count() 
4 
>>> session.query(Tag.name).distinct().count() 
3 

所以第二種形式給出正確的結果,但第一種形式沒有。這似乎發生在SQLite但不與Postgres。我有一個函數傳遞一個查詢對象來應用distinct子句,因此使用上面的第二種方法重寫所有內容將非常困難。有什麼明顯的我失蹤了?

回答

23

根據該文檔:

當存在時,PostgreSQL的方言會呈現DISTINCT ON (>)構建體。

因此,只有通過列表達式distinct()作品對PostgreSQL(因爲DISTINCT ON)。

在表達session.query(Tag).distinct(Tag.name).count() SQLAlchemy的忽略Tag.name併產生查詢(在所有領域的不同):

SELECT DISTINCT tag.country_id AS tag_country_id, tag.name AS tag_name 
FROM tag 

正如你所說,你的情況distinct(Tag.name)應用 - 所以不是隻是count()考慮使用此:

session.query(Tag).distinct(Tag.name).group_by(Tag.name).count() 

希望有幫助。

+1

感謝;我在關於「DISTINCT ON」的文檔中看到了這樣的評論,但由於文檔沒有明確說出'這是這種工作的唯一方式'或類似的東西,我沒有意識到這是暗示的。 –

11

當您使用session.query(Tag)時,您總是查詢整個Tag對象,因此如果您的表包含其他列,它將無法工作。

讓我們假設有一個id列,那麼查詢

sess.query(Tag).distinct(Tag.name) 

會產生:

SELECT DISTINCT tag.id AS tag_id, tag.name AS tag_name FROM tag 

的參數傳遞給不同的條款完全被忽略。

如果你真的只想從表中不同的名稱,你必須明確地只選擇相應的名稱:

sess.query(Tag.name).distinct() 

生產:

SELECT DISTINCT tag.name AS tag_name FROM tag 
相關問題