¿Es posible calcular la suma acumulativa (en ejecución) usando 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 modo que tengo un número (>1) de instancias de AModel en la base de datos, todas con 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 suma acumulativa. Entonces, en el caso anterior, me gustaría limitar el resultado a cumsum <= 2
Creo que en postgresql se puede lograr una suma acumulativa usando funciones de ventana. ¿Cómo se traduce esto al ORM?
A partir de la respuesta de Dima Kudosh y según 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 , lo que resultó en.
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" ASCLa respuesta de Dima Kudosh no fue resumir los resultados, pero lo anterior sí.
Para la posteridad, encontré que esta es una buena solución para mí. No necesitaba que el resultado fuera un QuerySet, por lo que podía permitirme hacer esto, ya que solo iba a trazar los datos usando 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)