Джанго Транчур аннотировать Количество не включающих часов с нулевыми строками

#python #django #postgresql

Вопрос:

У меня есть модель EventData

 class EventData(models.Model):  id = models.BigAutoField(primary_key=True)  created = models.DateTimeField()  session = models.ForeignKey(EventSession, on_delete=models.CASCADE)  name = models.ForeignKey(EventName, on_delete=models.CASCADE)  product = models.ForeignKey(Product, on_delete=models.CASCADE)  value = models.CharField(max_length=200)  

и запрос

 event_volume = IngestModels.EventData.objects.filter(product=my_product, created__date=selected_date)  .annotate(hour=TruncHour('created'))  .annotate(event_count=Count('*'))  .values("hour", "event_count")  

это дает такие результаты, как

час счетчик событий
2021-11-12 00:00:00 2
2021-11-12 01:00:00 2
2021-11-12 02:00:00 7
2021-11-12 05:00:00 5
2021-11-12 06:00:00 9
2021-11-12 09:00:00 10
2021-11-12 10:00:00 1
2021-11-12 12:00:00 9

Вы заметите, что бывают моменты, когда никаких событий не происходило, поэтому час в строке опущен. Мне бы очень хотелось, чтобы каждый час присутствовал и 0 в event_count колонке, если никаких событий не произошло. Так что что-то вроде:

час счетчик событий
2021-11-12 00:00:00 2
2021-11-12 01:00:00 2
2021-11-12 02:00:00 7
2021-11-12 03:00:00 0
2021-11-12 04:00:00 0
2021-11-12 05:00:00 5
2021-11-12 06:00:00 9
2021-11-12 07:00:00 0
2021-11-12 08:00:00 0
2021-11-12 09:00:00 10
2021-11-12 10:00:00 1
2021-11-12 11:00:00 0
2021-11-12 12:00:00 9

Любая помощь будет очень признательна! Я использую PostgreSQL в качестве своей базы данных.

Ответ №1:

Я не смог решить эту проблему с помощью ORM, но было тривиально заполнять данные обычным кодом Python.

 def time_series_pad_zeros(time_series):  result = []  for i in range(0,24):  found = False  for data in time_series:  if data['hour'].hour == i:  found = True  result.append({ "hour": i, "event_count": data['event_count'] })   if not found:  result.append({ "hour": i, "event_count": 0 })   return result