2013-06-20 9 views
21

でSQLAlchemyの中に明確な行を返すSQLAlchemyののQuery.distinct方法が一貫性なく動作している: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 

だから、2番目の形式は正しい結果を与えますが、最初の形はしていません。これはPostgresではなくSQLiteで起こるようです。私はそれに適用されるdistinct句を持っているクエリオブジェクトを渡される関数を持っているので、上のすべての2番目のアプローチを使用するすべてを書き換えることは非常に困難です。私が行方不明になっていることは明らかですか?ドキュメントによれば

答えて

23

存在する場合、PostgreSQLの方言は (>)構築物上DISTINCTをレンダリングします。

ので、PostgreSQLのためdistinct()作品に列式を渡すだけ(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 

をdistinct句の引数が完全に無視されます。

あなたが本当に唯一のテーブルとは別の名前にしたい場合は、明示的に名前だけを選択する必要があります。

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

は生成します。

SELECT DISTINCT tag.name AS tag_name FROM tag