2011-07-12 116 views
5

Estoy tratando de encontrar la duración acumulada de algunos eventos, los campos 'inicio' y 'final' son ambos campos django.db.models.DateTimeField.Cómo agregar un campo calculado con django ORM? (sin SQL en bruto)

Lo que me gustaría hacer debería haberse escrito así:

from django.db.models import F, Sum 
from my.models import Event 
Event.objects.aggregate(anything=Sum(F('start') - F('end'))) 
# this first example return: 
# AttributeError: 'ExpressionNode' object has no attribute 'split' 

# Ok I'll try more SQLish: 
Event.objects.extra(select={ 
         'extra_field': 'start - end' 
        }).aggregate(Sum('extra_field')) 
# this time: 
# FieldError: Cannot resolve keyword 'extra_field' into field. 

no puedo agreggate (Suma) empieza y termina por separado y luego restar en Python PORQUE DB no puede Suma objetos DateTime.

¿Una buena forma de hacerlo sin sql sin formato?

Respuesta

0

Esta respuesta no me satisface realmente qué, sin embargo, mi trabajo actual en torno a las obras pero no de DB calcula ...

reduce(lambda h, e: h + (e.end - e.start).total_seconds(), events, 0) 

Devuelve la duración de todos los eventos en el conjunto de consultas en segundos

Mejor SQL menos soluciones?

1

no puedo evitar Christophe sin Delorean, pero yo estaba golpeando este error y fue capaz de resolverlo en Django 1.8 como:

total_sum = Event.objects\ 
    .annotate(anything=Sum(F('start') - F('end')))\ 
    .aggregate(total_sum=Sum('anything'))['total_sum'] 

Cuando no pude actualizar todos mis dependencias a 1,8, lo encontró que esto funcione con Django 1.7.9 en la parte superior de MySQL:

totals = self.object_list.extra(Event.objects.extra(select={ 
    'extra_field': 'sum(start - end)' 
})[0] 
+1

Tu Delorean parece funcionar muy bien ;-). Pero, de hecho, si mi proyecto aún existe, no puedo construir la suma en SQL ya que compongo toneladas de sumas (domingos, días festivos, horas de la noche, horas del día ...) – christophe31

1

Si usted está en Postgres, a continuación, puede utilizar el paquete django-pg-utils y calcular en la base de datos. Emitir el campo de duración en segundos y luego tomar la suma

from pg_utils import Seconds 
from django.db.models import Sum 

Event.objects.aggregate(anything=Sum(Seconds(F('start') - F('end')))) 
Cuestiones relacionadas