Python SQLite与PostgreSQL的SQLAlchemy group_
对于我们正在构建的web应用程序,我们使用SQLite进行测试。最近我们想迁移到PostgreSQL。问题就是从这里开始的: 我们有这个SQLAlchemy模型(简化) 我想将所有Python SQLite与PostgreSQL的SQLAlchemy group_,python,postgresql,sqlite,group-by,sqlalchemy,Python,Postgresql,Sqlite,Group By,Sqlalchemy,对于我们正在构建的web应用程序,我们使用SQLite进行测试。最近我们想迁移到PostgreSQL。问题就是从这里开始的: 我们有这个SQLAlchemy模型(简化) 我想将所有实体按某个值进行分组,我喜欢这样做(简化): 在SQLite中,这是有效的。回想起来,我发现它没有意义,但SQLite确实有意义。我不能确定返回了哪些实体 现在在PostgrSQL中,我们得到了以下错误: sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingErr
实体
按某个值
进行分组,我喜欢这样做(简化):
在SQLite中,这是有效的。回想起来,我发现它没有意义,但SQLite确实有意义。我不能确定返回了哪些实体
现在在PostgrSQL中,我们得到了以下错误:
sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "entity.id" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT entity.id AS entity_id, entity.i_want_this AS entity_not...
^
[SQL: 'SELECT entity.id AS entity_id, entity.i_want_this AS entity_i_want_this, count(*) AS count_1 \nFROM entity GROUP BY entity.some_value']
这个错误完全有道理
所以我的第一个问题是:SQLite为什么允许这样做?它是如何做到的(使用了什么隐藏聚合)?
我的第二个问题很明显:如何使用PostgreSQL?
实际上我只对计数和第一个感兴趣,我想要这个值。所以我可以这样做:
groups = db.session.query(db.func.min(Entity.id), db.func.count()).group_by(Entity.some_value)
[(Entity.query.get(id_), count) for id_, count in groups]
但我不希望这些额外的get
查询
因此,我想选择第一个实体(id最小的实体)和按some\u value
分组的实体数,或者选择第一个I\u want\u this
和按some\u value
分组的计数
编辑以澄清:
- 我想按
某些值进行分组
(完成)
- 我想获得每个组中的实体数(完成)
- 我想获得每个组中id最低的实体(需要帮助)
- 或者,我想获得每组中id最低的实体的
I\u want\u this
值(需要帮助)
关于您的第一个问题,请检查:
然后,对结果集中的每个表达式分别计算一次
一组行。如果表达式是聚合表达式,则为
跨组中的所有行计算。否则,将对其进行评估
针对组内任意选择的一行。如果
结果集中有多个非聚合表达式,
然后对同一行计算所有此类表达式
关于第二个问题,考虑到您当前在SQLite中的查询也会或多或少地返回随机结果,您可能必须解释您实际想要实现的目标
编辑:
要获取每个组具有最小id的实体,可以使用查询。从构造中选择\u:
import sqlalchemy.sql as sa_sql
# create the aggregate/grouped query
grouped = sa_sql.select([sa_sql.func.min(Entity.id).label('min_id')])\
.group_by(Entity.some_value)\
.alias('grouped')
# join it with the full entities table
joined = sa_sql.join(Entity, grouped, grouped.c.min_id == Entity.id)
# and let sqlalchemy pull the entities from this statement:
session.query(Entity).select_from(joined)
这将生成以下SQL:
SELECT entities.id AS entities_id,
entities.i_want_this AS entities_i_want_this,
entities.some_value AS entities_some_value
FROM entities JOIN (SELECT min(entities.id) AS min_id
FROM entities GROUP BY entities.some_value) AS grouped
ON grouped.min_id = entities.id
关于第一个问题,请检查:
然后,对结果集中的每个表达式分别计算一次
一组行。如果表达式是聚合表达式,则为
跨组中的所有行计算。否则,将对其进行评估
针对组内任意选择的一行。如果
结果集中有多个非聚合表达式,
然后对同一行计算所有此类表达式
关于第二个问题,考虑到您当前在SQLite中的查询也会或多或少地返回随机结果,您可能必须解释您实际想要实现的目标
编辑:
要获取每个组具有最小id的实体,可以使用查询。从构造中选择\u:
import sqlalchemy.sql as sa_sql
# create the aggregate/grouped query
grouped = sa_sql.select([sa_sql.func.min(Entity.id).label('min_id')])\
.group_by(Entity.some_value)\
.alias('grouped')
# join it with the full entities table
joined = sa_sql.join(Entity, grouped, grouped.c.min_id == Entity.id)
# and let sqlalchemy pull the entities from this statement:
session.query(Entity).select_from(joined)
这将生成以下SQL:
SELECT entities.id AS entities_id,
entities.i_want_this AS entities_i_want_this,
entities.some_value AS entities_some_value
FROM entities JOIN (SELECT min(entities.id) AS min_id
FROM entities GROUP BY entities.some_value) AS grouped
ON grouped.min_id = entities.id
SQLite从组中的随机行返回一个值。但你说“第一”是什么意思?SQL表没有排序。我指的是在上一个代码片段中看到的id最低的实体。SQLite从组中的随机行返回一个值。但你说“第一”是什么意思?SQL表没有排序。我指的是上一段代码中id最低的实体。