У меня есть проект Django по замерам температуры. Я использую PostgreSQL как серверную часть базы данных. Допустим, моя модель:
class TemperatureMeasurement(models.Model):
time = models.DateTimeField(db_index=True)
temperature = models.FloatField(null=False)
Я проводил измерения каждую минуту в течение последних 6 месяцев или около того, что означает, что в этой таблице у меня около 270 тысяч строк. Я пишу 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 Панель инструментов отладки). Я читал об объектах Q()
из Django, но не уверен, как их использовать в этом случае. Я думал что-то вроде:
# ...
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. Можно ли как-нибудь оптимизировать этот запрос?
Спасибо.