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

时间:2013-06-20 20:28:30

标签: 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

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

2 个答案:

答案 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