Skip to content

Commit e0f52ec

Browse files
committed
fix _get_distinct_timezone
the previous query did not actually get distinct timezones
1 parent 70d381b commit e0f52ec

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

django_celery_beat/schedulers.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
"""Beat Scheduler Implementation."""
2+
from __future__ import annotations
3+
24
import datetime
35
import logging
46
import math
@@ -15,7 +17,7 @@
1517
from celery.utils.time import maybe_make_aware
1618
from django.conf import settings
1719
from django.core.exceptions import ObjectDoesNotExist
18-
from django.db import close_old_connections, transaction
20+
from django.db import close_old_connections, connection, transaction
1921
from django.db.models import Case, F, IntegerField, Q, When
2022
from django.db.models.functions import Cast
2123
from django.db.utils import DatabaseError, InterfaceError
@@ -337,7 +339,7 @@ def _get_crontab_exclude_query(self):
337339
+ 24
338340
) % 24
339341
)
340-
for timezone_name in self._get_unique_timezone_names()
342+
for timezone_name in self._get_unique_timezones()
341343
],
342344
# Default case - use hour as is
343345
default=F('hour_int')
@@ -365,11 +367,25 @@ def _get_valid_hour_formats(self):
365367
f"{hour:02d}" for hour in range(10)
366368
]
367369

368-
def _get_unique_timezone_names(self):
369-
"""Get a list of all unique timezone names used in CrontabSchedule"""
370-
return CrontabSchedule.objects.values_list(
371-
'timezone', flat=True
372-
).distinct()
370+
def _get_unique_timezones(self) -> set[ZoneInfo]:
371+
"""Get a set of all unique timezones used in CrontabSchedule"""
372+
# sqlite does not support distinct on a column
373+
if connection.vendor == 'sqlite':
374+
return set(
375+
CrontabSchedule.objects.values_list(
376+
'timezone', flat=True
377+
)
378+
)
379+
380+
return set(
381+
CrontabSchedule.objects.order_by(
382+
'timezone'
383+
).distinct(
384+
'timezone'
385+
).values_list(
386+
'timezone', flat=True
387+
)
388+
)
373389

374390
def _get_timezone_offset(self, timezone_name):
375391
"""

t/unit/test_schedulers.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1224,6 +1224,21 @@ def test_crontab_special_hour_four(self):
12241224
# The hour=4 task should never be excluded
12251225
assert task_hour_four.id not in excluded_tasks
12261226

1227+
@pytest.mark.django_db
1228+
def test_get_unique_timezones(self):
1229+
"""
1230+
Test that get unique timezones returns a list of unique timezones
1231+
"""
1232+
# Create 2 crontabs with same timezone, and 1 with different timezone
1233+
CrontabSchedule.objects.create(hour='4', timezone='UTC')
1234+
CrontabSchedule.objects.create(hour='4', timezone='UTC')
1235+
CrontabSchedule.objects.create(hour='4', timezone='America/New_York')
1236+
1237+
timezones = self.s._get_unique_timezones()
1238+
1239+
assert len(timezones) == 2
1240+
assert set(timezones) == {ZoneInfo('UTC'), ZoneInfo('America/New_York')}
1241+
12271242
@pytest.mark.django_db
12281243
@patch('django_celery_beat.schedulers.aware_now')
12291244
@patch('django.utils.timezone.get_current_timezone')

0 commit comments

Comments
 (0)