Django查询,基于N分钟计数

时间:2015-01-21 17:20:14

标签: django django-queryset

我有以下型号:

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'))

但我有几个问题:

  1. 如果我有一行,我有间隔的计数。当我没有排,我没有:{Datetime(t'): O }
  2. 每分钟计数。我必须总结N分钟来分发。
  3. 它不是Datetime而是(小时,分钟)夫妻。
  4. 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最好的方式吗?

0 个答案:

没有答案