Suma acumulativa (en ejecución) con django orm y postgresql

¿Es posible calcular la sum acumulativa (en ejecución) utilizando el orm de django? Considere el siguiente modelo:

class AModel(models.Model): a_number = models.IntegerField() 

con un conjunto de datos donde a_number = 1 . De tal manera que tengo un número (> 1) de instancias de AModel en la base de datos, todas con un a_number=1 . Me gustaría poder devolver lo siguiente:

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

Idealmente, me gustaría poder limitar / filtrar la sum acumulada. Así que en el caso anterior me gustaría limitar el resultado a la cumsum <= 2

Creo que en postgresql se puede lograr una sum acumulada utilizando las funciones de ventana. ¿Cómo se traduce esto al ORM?

De la respuesta de Dima Kudosh y basada en https://stackoverflow.com/a/5700744/2240489 , tuve que hacer lo siguiente: eliminé la referencia a PARTITION BY en el sql y la reemplacé con ORDER BY resultado.

 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') 

Esto da el siguiente 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 

La respuesta de Dima Kudosh no fue sumr los resultados, pero sí lo anterior.

Para referencia, comenzando con Django 2.0 es posible usar la función de Window para lograr este resultado:

 AModel.objects.annotate(cumsum=Window(Sum('a_number'), order_by=F('id').Asc()))\ .values('id', 'cumsum').order_by('id', 'cumsum') 

Para la posteridad, encontré que esta es una buena solución para mí. No necesitaba el resultado para ser un QuerySet, por lo que podía darme el lujo de hacer esto, ya que solo iba a trazar los datos utilizando D3.js:

 import numpy as np import datettime today = datetime.datetime.date() raw_data = MyModel.objects.filter('date'=today).values_list('a_number', flat=True) cumsum = np.cumsum(raw_data) 

Puedes intentar hacer esto con la expresión funcional .

 from django.db.models import Func, Sum AModel.objects.annotate(cumsum=Func(Sum('a_number'), template='%(expressions)s OVER (PARTITION BY %(partition_by)s)', partition_by='id')).values('id', 'cumsum').order_by('id') 

Mira esto

 AModel.objects.order_by("id").extra(select={"cumsum":'SELECT SUM(m.a_number) FROM table_name m WHERE m.id <= table_name.id'}).values('id', 'cumsum') 

donde table_name debe ser el nombre de la tabla en la base de datos.