Django ORM:从大数据集中每天检索第一个度量值

2024-09-26 17:40:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个关于温度测量的Django项目。我使用PostgreSQL作为数据库后端。假设我的模型是:

class TemperatureMeasurement(models.Model):
    time = models.DateTimeField(db_index=True)
    temperature = models.FloatField(null=False)

在过去6个月左右的时间里,我每分钟都进行一次测量,这意味着我在这张表中大约有270k行。我正在编写一个API,它应该返回给定日期范围内每天的第一个温度记录。我有这样的想法:

def TemperatureBetween(APIView):
    # ...
    def get(self, request, *args, **kwargs):
        date_from = datetime.strptime(kwargs['date_from'], '%Y-%m-%d')
        date_to = datetime.strptime(kwargs['date_to'], '%Y-%m-%d')

        all_measurements = TemperatureMeasurement.objects.filter(
            time__gte=date_from,
            time__lt=date_to,
        ).order_by('time')

        r = []
        current_day = date_from

        while current_day < date_to:
            day_measurement = all_measurements.filter(
                time__gte=current_day,
            ).first()
            r.append([day_measurement.time, day_measurement.temperature])
            current_day += timedelta(hours=24)

        return Response(r)        

我知道这种方法可能远远不是最佳的,因为据我所知,我在时间范围内进行的数据库查询至少与天数相同(这也是Django Debug Toolbar告诉我的)。我已经读过Django的Q()对象,但我不确定在这种情况下如何使用它们。我的想法是:

        # ...
        query = Q()
        while current_day < date_to:
            query |= Q(time__gte=current_day).first()
            current_day += timedelta(hours=24)

        temperature_measurements = TemperatureMeasurement.objects.filter(query)
        # ... process data...

但这不起作用,因为Q()对象没有“first”属性。我有没有办法优化这个查询

多谢各位


Tags: todjangofromdatetimemodelscurrentfilter
1条回答
网友
1楼 · 发布于 2024-09-26 17:40:08

试试这个

from django.db.models.functions import TruncDay

daily_first_measurement = (TemperatureMeasurement.objects
                           .filter(time__gte=date_from, time__lt=date_to)
                           .annotate(day=TruncDay(time))
                           .order_by('day', 'time')
                           .distinct('day')
)

这将返回从date_fromdate_to范围内的每天TemperatureMeasurement的第一条记录。对于阅读本文的其他人,postgresql是此查询的基础数据库(以利用distinct

相关问题 更多 >

    热门问题