我有以下型号:
class Indicator(TimeStampedModel):
name = models.CharField(max_length=200)
description = models.TextField(max_length=1000)
class IndicatorValue(models.Model):
time = models.DateTimeField(db_index=True)
indicator = models.ForeignKey(Indicator)
value = models.IntegerField()
我想得到一个数组,其中包含每N分钟时段的指标X的IndicatorValue数量:
[
{Datetime(t): Count(IndicatorValue == X, t<=time<t+N)}
{Datetime(t+N minute): Count(IndicatorValue == X, t+N<=time<t+2N)}
]
我试过了:
IndicatorValue.objects.filter(indicator_id=X).extra({'hour': "date_part(\'hour\', \"time\")", 'minute': "date_part(\'minute\', \"time\")"}).values('hour', 'minute').annotate(count=Count('id'))
但我有几个问题:
{Datetime(t'): O }
。Datetime
而是(小时,分钟)夫妻。Django是否有解决此问题的简单方法?
EDIT1:
我发现date_trunc
保持Datetime
格式:
IndicatorValue.objects.filter(indicator_id=6).extra({'minute_interval': "date_trunc(\'minute\', \"time\")"}).values('minute_interval').annotate(count=Count('id'))
第1点和第1点2仍未解决。
EDIT2:
我找到了获得N分钟间隔的方法:
IndicatorValue.objects.filter(indicator_id=6).extra({'minute_interval': "SELECT date_trunc(\'hour\', \"time\") + INTERVAL \'5 min\' * ROUND(date_part(\'minute\', \"time\") / 5.0) "}).values('minute_interval').annotate(count=Count('id'))
这会生成以下查询:
SELECT (SELECT date_trunc('hour', "time") + INTERVAL '5 min' * ROUND(date_part('minute', "time") / 5.0) ) AS "minute_interval", COUNT("app_monitoring_indicatorvalue"."id") AS "count" FROM "app_monitoring_indicatorvalue" WHERE "app_monitoring_indicatorvalue"."indicator_id" = 6 GROUP BY (SELECT date_trunc('hour', "time") + INTERVAL '5 min' * ROUND(date_part('minute', "time") / 5.0) )
使用PostgreSQL
测试解决方案:Source。
第1点仍然存在。
EDIT3:
我有一个基于execute
的解决方案:
from django.db import connection
cursor = connection.cursor()
cursor.execute('''\
select g, count(a.id) \
from generate_series( \
%(from)s::timestamp, \
%(to)s::timestamp, \
%(slice)s::interval \
) as g \
left outer join app_monitoring_indicatorvalue as a on \
a.time >= g and a.time < g + %(slice)s::interval \
group by g \
order by g \
''', {'slice': '5 minutes', 'from': '20150121 9:00', 'to': '20150121 13:00'})
cursor.fetchall()
这解决了所有问题。我无法使用raw
,因为我无法返回primary key
IntervalValue
。
这是django最好的方式吗?