使用SQLite在SQLAlchemy中返回不同的行

Eli*_*ght 39 python sqlite sqlalchemy

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
Run Code Online (Sandbox Code Playgroud)

所以第二种形式给出了正确的结果,但第一种形式却没有.这似乎发生在SQLite中,但不适用于Postgres.我有一个函数,它传递一个查询对象来distinct应用一个子句,所以重写所有内容非常困难,最好使用上面的第二种方法.有什么明显的东西让我失踪吗?

ale*_*cxe 48

根据文件:

如果存在,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
Run Code Online (Sandbox Code Playgroud)

如你所说,在你的情况下distinct(Tag.name)应用 - 所以不要只count()考虑使用这个:

session.query(Tag).distinct(Tag.name).group_by(Tag.name).count()
Run Code Online (Sandbox Code Playgroud)

希望有所帮助.


mat*_*ata 22

当您一直使用session.query(Tag)查询整个Tag对象时,如果您的表包含其他列,它将无法工作.

我们假设有一id列,然后是查询

sess.query(Tag).distinct(Tag.name)
Run Code Online (Sandbox Code Playgroud)

将产生:

SELECT DISTINCT tag.id AS tag_id, tag.name AS tag_name FROM tag
Run Code Online (Sandbox Code Playgroud)

distinct子句的参数被完全忽略.

如果您真的只想要表中的不同名称,则必须只显式选择名称:

sess.query(Tag.name).distinct()
Run Code Online (Sandbox Code Playgroud)

生产:

SELECT DISTINCT tag.name AS tag_name FROM tag
Run Code Online (Sandbox Code Playgroud)