Переход на TZ aware datetime в Django, PostgreSQL timestamp
Я использую Django ORM для доступа к данным PostgreSQl. База данных относительно большая ~100 таблиц, некоторые из которых содержат десятки миллионов записей. Я перехожу с Django 4.2 на Django 5.0, в котором по умолчанию стоит USE_TZ = True
, и я хочу сохранить это, так что после перехода - надеюсь, в моей системе не будет наивных датировок.
У меня есть такие модели, как:
class MyExistingModel(BaseModel):
name = models.CharField(max_length=100, unique=True, null=False, blank=False)
date_created = models.DateTimeField(auto_now_add=True)
...и то, что я наблюдаю в большинстве своих моделей, выглядит следующим образом:
In [6]: mem = MyExistingModel.objects.create(name="new record")
In [7]: mem.date_created
Out[7]: datetime.datetime(2024, 5, 23, 6, 15, 25, 885356, tzinfo=datetime.timezone.utc)
In [8]: MyExistingModel.objects.get(name="new record").date_created
Out[8]: datetime.datetime(2024, 5, 23, 1, 15, 25, 885356)
Одна и та же запись, одно и то же поле - два разных формата времени даты: aware и naive. При смешивании этих двух форматов я, конечно же, получаю ошибку типа:
TypeError: can't compare offset-naive and offset-aware datetimes
Это большая проблема, так как я вряд ли смогу контролировать каждое место, где используется DateTimeField
.
Похоже, что причина этого в том, что date_created
в моем PostgreSQL, который был создан Django давным-давно, имеет вид timestamp without time zone
. Это то, что я вижу с помощью редактора DB. Однако это не относится ко всем таблицам. Есть таблицы, в которых некоторые поля имеют тип timestamp with time zone
. Я полагаю, это зависит от того, какая версия Django использовалась для создания этих таблиц/полей. Имеет смысл?
В общем, я попробовал перенести вручную одно поле, и тогда я получил последовательное поведение: всегда TZ знает временные метки.
Вопрос:
Действительно ли мне нужно перенести все таблицы в системе, чтобы получить чистую ситуацию? Две проблемы: возможно, длительный простой и работа с ошибками, поскольку мне нужно быть довольно осторожным в определении местоположения только тех DateTimeField
полей, которые действительно не имеют часового пояса.