ORM-запрос вытягивает объекты за пределы диапазона дат из-за изменения часового пояса

У меня есть часть унаследованного кода, который использует интерполированный SQL с psycopg2 для выполнения запроса. Однако я хотел убрать это и сделать так, чтобы код использовал только ORM. Однако у меня возникла проблема, когда мой ORM-запрос выводит результаты за пределы заданного диапазона дат, когда часовой пояс установлен не на UTC.

Например, учитывая следующую модель:

class Dinner(models.Model):
    eaten_at = models.DateTimeField()

И давая следующие произвольные объекты, которые есть в моей базе данных:

Dinner(id=1, eaten_at=2022-02-23 16:58:11+00:00)
Dinner(id=2, eaten_at=2022-02-23 23:59:59+00:00)
Dinner(id=3, eaten_at=2022-02-24 00:00:00+00:00)
Dinner(id=4, eaten_at=2022-02-24 00:00:00+00:00)

Я хотел выполнить запрос для Ужинов, съеденных 2022-02-24 или после 2022-02-24

eaten_after_date = datetime.datetime.combine(datetime.datetime.strptime("2022-02-24", "%Y-%m-%d"),datetime.time(0, 0, 0))
# datetime.datetime(2022, 2, 24, 0, 0)

Мой код Psycopg2 выглядел следующим образом:

cursor.execute("SELECT * FROM dinner WHERE dinner.eaten_at >= %s with time zone", eaten_after_date) 

Как и ожидалось, в результате получаются две строки с соответствующими ID 3 и 4.

Я переписал это, используя только ORM, следующим образом:

Dinner.objects.filter(eaten_at__gte=eaten_after_date)

И в некоторых случаях это работает. Однако, когда у меня в настройках есть следующее:

TIME_ZONE = "Asia/Tokyo" 

Я возвращаю объекты до 24-го (в данном конкретном примере - возвращаются ВСЕ строки). Например, получение первого отсортированного результата возвращает запись, начиная с 23-го:

record.objects.filter(meta_end_date__gte=eaten_after_date).order_by('eaten_at').first().eaten_after_date
>>> 2022-02-23 16:58:11+00:00

Это странно - мое указанное время даты datetime.datetime(2022, 2, 24, 0, 0), а я получаю результаты от 23-го числа! Я уверен, что это какая-то проблема с часовым поясом при интерполяции запроса. Однако... я не знаю, как это исправить.

Я пробовал:

eaten_after_date = timezone.make_aware(eaten_after_date)
# and 
eaten_after_date = eaten_after_date.astimezone()

Однако я совершенно не могу воспроизвести результаты запроса из моего предыдущего запроса Psycopg2 в чистый запрос ORM.

Мне кажется, что я упускаю что-то очень простое, и я совершенно не знаю что.

Вернуться на верх