Python SQLAlchemy:如何正确使用group_by()(仅使用\u full\u group_by)?
我正在尝试使用Python SQLAlchemy:如何正确使用group_by()(仅使用\u full\u group_by)?,python,mysql,sql,sqlalchemy,greatest-n-per-group,Python,Mysql,Sql,Sqlalchemy,Greatest N Per Group,我正在尝试使用mysql+mysqlconnector引擎的SQLAlchemy的groupby()函数: rows = session.query(MyModel) \ .order_by(MyModel.published_date.desc()) \ .group_by(MyModel.category_id) \ .all() 它可以与SQLite一起工作,但对于MySQL,我得到以下错误: [42000][1055] Expressio
mysql+mysqlconnector
引擎的SQLAlchemy的groupby()
函数:
rows = session.query(MyModel) \
.order_by(MyModel.published_date.desc()) \
.group_by(MyModel.category_id) \
.all()
它可以与SQLite一起工作,但对于MySQL,我得到以下错误:
[42000][1055] Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column '...' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
我知道,但我想利用SQLAlchemy的优势
什么是SQLAlchemy的正确解决方案
提前感谢使用定义良好的行为形成查询的一种方法是使用左连接
,在每个类别id
中查找MyModel
行,这些行没有与更大的发布日期匹配的行
:
my_model_alias = aliased(MyModel)
rows = session.query(MyModel).\
outerjoin(my_model_alias,
and_(my_model_alias.category_id == MyModel.category_id,
my_model_alias.published_date > MyModel.published_date)).\
filter(my_model_alias.id == None).\
all()
这将适用于任何SQL DBMS。在SQLite 3.25.0和MySQL 8(以及许多其他版本)中,您可以使用窗口函数实现相同的功能:
sq = session.query(
MyModel,
func.row_number().
over(partition_by=MyModel.category_id,
order_by=MyModel.published_date.desc()).label('rn')).\
subquery()
my_model_alias = aliased(MyModel, sq)
rows = session.query(my_model_alias).\
filter(sq.c.rn == 1).\
all()
当然,如果在联接中使用结果,也可以使用分组方式:
max_pub_dates = session.query(
MyModel.category_id,
func.max(MyModel.published_date).label('published_date')).\
group_by(MyModel.category_id).\
subquery()
rows = session.query(MyModel).\
join(max_pub_dates,
and_(max_pub_dates.category_id == MyModel.category_id,
max_pub_dates.published_date == MyModel.published_date)).\
all()
正确的解决方案是修复错误的sql。放置sql查询,我们可以帮助判断它的错误所在查询在SQLite afaic中实际上不起作用;当使用min()
或max()
聚合时,它仅保证“裸/非聚合列”的某些行为:。它在MySQL中也从来没有真正起过作用(就像在定义良好的行为中一样)。看起来您正在尝试执行一个查询,选择最新的MyModel
percategory\u id
bypublished\u date
,对吗?@IljaEverilä它在SQLite中为我工作。奇怪的是的,我正在努力获取每个类别中最新/最好的。它在MySQL中使用setSQL\u mode=“traditional”代码>,这是我想避免的。它可能会返回您大部分时间都在寻找的结果,但行为没有得到很好的定义,并且可能会中断,就像MySQL最终开始更严格地遵循SQL标准一样。根据您的查询,您可能需要这样一个简单的解决方案