与django orm和postgresql的累积(运行)总和

wrd*_*man 6 python django postgresql orm

是否可以使用django的orm来计算累积(运行)总和?考虑以下模型:

class AModel(models.Model):
    a_number = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

用一组数据在哪里a_number = 1.这样我AModel在数据库中有一个数字(> 1)的所有实例a_number=1.我希望能够返回以下内容:

AModel.objects.annotate(cumsum=??).values('id', 'cumsum').order_by('id')
>>> ({id: 1, cumsum: 1}, {id: 2, cumsum: 2}, ... {id: N, cumsum: N})
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望能够限制/过滤累积总和.所以在上面的例子中,我想将结果限制为cumsum <= 2

我相信在postgresql中可以使用窗口函数实现累积和.这怎么翻译成ORM?

wrd*_*man 5

根据 Dima Kudosh 的回答并基于/sf/answers/399052111/我必须执行以下操作:我删除了PARTITION BYsql 中对的引用并替换为ORDER BY结果。

AModel.objects.annotate(
    cumsum=Func(
        Sum('a_number'), 
        template='%(expressions)s OVER (ORDER BY %(order_by)s)', 
        order_by="id"
    ) 
).values('id', 'cumsum').order_by('id', 'cumsum')
Run Code Online (Sandbox Code Playgroud)

这给出了以下 sql:

SELECT "amodel"."id",
SUM("amodel"."a_number") 
OVER (ORDER BY id) AS "cumsum" 
FROM "amodel" 
GROUP BY "amodel"."id" 
ORDER BY "amodel"."id" ASC, "cumsum" ASC
Run Code Online (Sandbox Code Playgroud)

迪玛·库多什(Dima Kudosh)的回答不是对结果进行总结,而是对上述结果进行总结。


Cam*_*mpi 5

作为参考,从Django 2.0开始,可以使用Window函数来实现以下结果:

AModel.objects.annotate(cumsum=Window(Sum('a_number'), order_by=F('id').asc()))\
              .values('id', 'cumsum').order_by('id', 'cumsum')
Run Code Online (Sandbox Code Playgroud)