2011-07-12 20 views
5

我试图找到一些事件的累计持续时间,'开始'和'结束'字段都是django.db.models.DateTimeField字段。如何使用django ORM来聚合计算字段? (没有原始SQL)

我想这样做本来应该这样写:

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. 

我不能agreggate(SUM)开始,分别终止然后在。减去蟒蛇因为DB不能总datetime对象。

一个没有原始sql的好方法吗?

回答

0

这个答案并不真的满足我呢,我目前的工作围绕的作品,但它不是分贝计算...

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

它返回的所有事件的持续时间在查询集以秒

更好的SQL解决方案?

1

不禁克里斯托夫没有德罗宁,但我打这个错误,并能解决它在Django 1.8,如:

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

当我不能我所有的依赖关系升级到1.8,我发现这与Django的1.7.9关于MySQL的顶部工作:

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

您的Delorean似乎很好地运行;-)。但事实上,如果我的项目仍然存在,那么我无法再构建SQL中的总和,因为我弥补了数量巨大的数额(星期日,星期日,夜晚,白天......) – christophe31

1

如果你是Postgres的,那么你可以使用django-pg-utils包和数据库计算。将持续时间字段转换为秒数,然后取得总和

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

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