如何使用 django ORM 聚合计算字段? (没有原始 SQL)

发布于 2024-11-19 20:27:32 字数 665 浏览 1 评论 0原文

我试图找到某些事件的累积持续时间,“开始”和“结束”字段都是 django.db.models.DateTimeField 字段。

我想做的应该这样写:

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.

我无法分别聚合(求和)开始和结束,然后在 python 中减去,因为 DB 无法对 DateTime 对象求和。

没有原始 sql 的好方法吗?

I'm trying to find the cumulated duration of some events, 'start' and 'end' field are both django.db.models.DateTimeField fields.

What I would like to do should have been written like this:

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.

I can't agreggate (Sum) start and end separately then substract in python because DB can't Sum DateTime objects.

A good way to do without raw sql?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

暮倦 2024-11-26 20:27:32

没有 Delorean 就无法帮助 Christophe,但我遇到了这个错误,并且能够在 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]

Can't help Christophe without a Delorean, but I was hitting this error and was able to solve it in Django 1.8 like:

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

When I couldn't upgrade all my dependencies to 1.8, I found this to work with Django 1.7.9 on top of MySQL:

totals = self.object_list.extra(Event.objects.extra(select={
    'extra_field': 'sum(start - end)'
})[0]
樱花细雨 2024-11-26 20:27:32

如果您使用的是 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'))))

If you are on Postgres, then you can use the django-pg-utils package and compute in the database. Cast the duration field into seconds and then take the sum

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

Event.objects.aggregate(anything=Sum(Seconds(F('start') - F('end'))))
少女七分熟 2024-11-26 20:27:32

这个答案还没有真正让我满意,我当前的工作是有效的,但它不是数据库计算的...

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

它返回查询集中所有事件的持续时间(以秒为单位)

更好的更少 SQL 的解决方案?

This answer don't realy satisfy me yet, my current work around works but it's not DB computed...

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

It returns the duration of all events in the queryset in seconds

Better SQL less solutions?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文