SQLAlchemyの Query.distinct メソッドは一貫性のない動作をしています:
>>> [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番目の形式では正しい結果が得られますが、最初の形式では正しくありません。これはSQLiteで発生するようですが、Postgresでは発生しません。クエリオブジェクトを渡してdistinct
句を適用する関数があるので、上記の2番目のアプローチを使用してすべてを書き換えることは非常に困難です。私が行方不明になっていることは明らかですか?
ドキュメントによると:
存在する場合、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()
お役に立てば幸いです。
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