You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Django中用SQLite儒略日做原生SQL聚合时遇类型错误

问题解决:计算last_played与当前时间天数差的平均值

你遇到的错误是因为Django的aggregate()方法要求传入的是Django内置的聚合表达式(如Avg、Sum),而RawSQL本身不属于聚合表达式类型,因此无法被识别。以下是两种可行的解决方案:

方案一:直接使用原生SQL查询(最直接)

绕过ORM的聚合限制,直接执行原生SQL语句:

from django.db import connection

def get_avg_days_last_played():
    with connection.cursor() as cursor:
        # 替换`song_song`为你的实际表名(Django默认格式为「应用名_模型名」)
        cursor.execute("""
            SELECT AVG(julianday('now') - julianday(last_played)) FROM song_song;
        """)
        result = cursor.fetchone()
    # 无记录时返回None
    return result[0] if result else None

average_days_last_played = get_avg_days_last_played()

方案二:自定义聚合函数(符合Django ORM规范)

通过自定义聚合类,让Django识别你的SQL逻辑为合法的聚合表达式:

from django.db.models import Aggregate, FloatField

class AvgDaysSinceLastPlayed(Aggregate):
    function = 'AVG'
    # 模板中注入SQL逻辑,%(expressions)s会自动替换为传入的字段名
    template = "%(function)s(julianday('now') - julianday(%(expressions)s))"
    output_field = FloatField()

# 使用自定义聚合计算平均值
average_days_last_played = Song.objects.aggregate(
    avg_days_last_played=AvgDaysSinceLastPlayed('last_played')
)['avg_days_last_played']

注意事项

确保代码中的字段名与你模型中定义的一致:问题描述中提到的是last_played,但你原代码里用了played_at,需统一避免字段名错误。

内容的提问来源于stack exchange,提问作者Tjorriemorrie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 06:59:58