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
所以第二种形式给出了正确的结果,但第一种形式却没有。这似乎发生在SQLite中,但不适用于Postgres。我有一个函数,它传递一个查询对象,以便应用distinct
子句,因此重写所有内容非常困难,最好使用上面的第二种方法。有什么明显的东西我不见了吗?
答案 0 :(得分:42)
根据文件:
如果存在,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}}
希望有所帮助。
答案 1 :(得分:17)
当您使用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