Django如何对日期范围进行平均值计算

4

我有一个简单的基于Django构建的运行时间监控应用程序,它检查站点是否未响应ping请求。它在“dt”列中存储ping的时间戳,并在“ms”列中存储毫秒级响应时间。该站点每分钟被ping一次,并将条目放入数据库中。

Django模型如下:

class Uptime (models.Model):
    user = models.ForeignKey(User)
    dt = models.DateTimeField()
    ms = models.IntegerField()

我希望能够从dt列中逐日获取数据,并计算每天的平均ms响应时间。虽然每天有1440个条目,但我只想获取某一天(例如2013年4月19日)并得到平均的ms响应时间。我使用的代码明显是错误的,但我感觉自己在正确的轨道上。请问如何让这段代码正常工作?

       output_date = Uptime.objects.filter(user = request.user).values_list('dt', flat = True).filter(dt__range=(startTime, endTime)).order_by('dt').extra(select={'day': 'extract( day from dt )'}).values('day')
       output_ms = Uptime.objects.filter(user = request.user).filter(dt__range=(startTime, endTime)).extra(select={'day': 'date( dt )'}).values('day').aggregate(Avg('ms'))

感谢您!

我为此制作了一个定制解决方案。看看它是否有帮助:https://stackoverflow.com/questions/68153810/average-of-datetimefield-django/68154801#68154801 - Rohan Pahwa
1个回答

5

您需要进行注释才能进行分组。Django的ORM没有提取仅日期的内容,因此您需要向查询添加“extra”参数,指定仅使用日期。然后选择仅这些值并进行注释。

请尝试以下操作:

Uptime.objects.filter(user=request.user).extra({'_date': 'Date(dt)'}).values('_date').annotate(avgMs=Avg('ms'))

这应该会给你一个如下的列表:
[{'_date': datetime.date(2012, 7, 5), 'avgMs': 300},{'_date': datetime.date(2012, 7, 6), 'avgMs': 350}]

顺便提一下,当涉及到扩展时,如果你有几亿行数据,这将开始变得缓慢。原因是你不能仅在日期部分上建立数据库索引,而且看起来你只想进行每日聚合。我建议你在MySQL上建立一个单独的日期列(带索引),并另外再建立一个时间列,表示一天中的秒数。这将使未来的查询速度更快。 - aminland
谢谢aminland!可扩展性是一个重要问题,所以我很感谢你的见解。 - Ryan M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接