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

Python 使用SQLite在SQLAlchemy中返回不同的行,python,sqlite,sqlalchemy,Python,Sqlite,Sqlalchemy,SQLAlchemy的方法行为不一致: >>> [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 因此,第二种形式给出

SQLAlchemy的方法行为不一致:

>>> [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
子句,因此使用上面的第二种方法重写所有内容是非常困难的。有什么明显的东西我遗漏了吗?

根据文档:

当存在时,Postgresql方言将在 (>)构造

因此,将列表达式传递给
distinct()
仅适用于PostgreSQL(因为在
上有
distinct)

在表达式
session.query(Tag).distinct(Tag.name).count()
sqlalchemy忽略
Tag.name
并生成查询(在所有字段上都是distinct):

正如你所说的,在你的例子中,<代码>区分(tag .name)< /代码> -因此,而不是只是<代码> CONTUTE()/代码>考虑使用这个:

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

谢谢我在文档中看到了关于
的评论,但由于文档没有明确地说“这是唯一可行的方法”或类似的话,我没有意识到这是隐含的。否决是因为推广特定于SQLite的扩展,它允许选择不由GROUP by子句确定的非聚合列,从而产生不确定的结果(由于
count()
,这里不太准确,但存在正确的解决方案,就像在另一个答案中一样)。@IljaEverilänice duplet downvote,完全是出于意外。@IljaEverilä感谢您的评论,否决票并不常见,但肯定是一种期望的行为。我并没有在这里推广任何东西,只是试图帮助回答一个特定于sqlite的问题。虽然这是非常事后诸葛亮的,但考虑到你正在回答一个特定于sqlite的问题,为什么不干脆删除
distinct(Tag.name)
,因为它在SQLite中是无用的,并且由于分组的原因,大多数SQL DBMS都会拒绝查询。在double dv上,我确实分享了有趣q/a的链接(一种方式或另一种方式)。这将是一个很好的复制目标,如果不是为了被接受的答案,尽管您很好地解释了为什么
distinct()
甚至接受表达式作为参数。
SELECT DISTINCT tag.name AS tag_name FROM tag