51

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 番目の方法を使用してすべてを書き直すことは非常に困難です。私が行方不明であることは明らかですか?

4

2 に答える 2

67

ドキュメントによると:

存在する場合、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()

それが役立つことを願っています。

于 2013-06-20T21:15:22.137 に答える
36

使用する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
于 2013-06-20T21:25:09.013 に答える