Почему Django создает столбцы меток времени Postgres с часовыми поясами? - PullRequest
5 голосов
/ 12 ноября 2011

Я думал, что Django создал столбцы даты и времени, которые не зависят от часового пояса, но когда я посмотрел на свою таблицу Postgres, я увидел, что записанные там значения содержат информацию о часовом поясе.

В дальнейшем я обнаружил, что сервер Postgresнаправляет Django для создания столбцов, использующих часовые пояса.

Из django / db / backends / postgresql / creation.py:

data_types = {
        ...
        'DateTimeField':     'timestamp with time zone',
        ...

Схема показывает, что созданный столбец указан как «отметка времени»с часовым поясом ".

CREATE TABLE notification_notice
(
  ...
  created timestamp with time zone NOT NULL,
  ...

Журнал Postgres показывает отправленный оператор обновления.Django создал оператор SQL, который использовал UTC в качестве часового пояса, как указано в моем файле настроек Django.

UPDATE "notification_notice" SET "sender_id" = 1, "group_id" = NULL, "notice_type_id" = 1, "content_type_id" = 21, "object_id" = 3, "created" = E'2011-11-11 22:31:08.022148' WHERE "notification_notice"."id" = 14

Так выглядит моя таблица.Созданный столбец имеет временную метку, которая имеет «-08» для своего часового пояса.Postgres должен проверять часовой пояс моих системных часов, чтобы найти часовой пояс.

my_db=# select * from notification_notice limit 1;
 id | sender_id | group_id | notice_type_id | content_type_id | object_id |           created            | last_interaction_time 
----+-----------+----------+----------------+-----------------+-----------+------------------------------+-----------------------
  1 |           |        3 |             21 |              53 |         6 | 2011-11-11 14:31:02.98882-08 | 
(1 row)

Вопросы:
Разве у Django нет политики переключения на часовые пояса?
ПочемуБэкэнд Postgres использует часовые пояса для моделей. DateTimeField?Это требуется Postgres?
Есть ли способ заставить Django создавать столбцы меток времени в Postgres, которые не используют часовой пояс?

Ответы [ 3 ]

16 голосов
/ 12 ноября 2011

Плохая новость заключается в том, что корень проблемы в реализации Python datetime.

Хорошей новостью является то, что у Django есть открытый билет на эту проблему.

Плохая новость заключается в том, что билет был открыт в 2006 году.

Хорошая новость заключается в том, что недавнее предложение 1010 * более полезно для чтения и, похоже, находится в разработке.Нить, содержащая предложение, длинна, но очень информативна.

Плохая новость заключается в том, что предложение сводится к тому, что «это настоящий беспорядок».(Тем не менее, он находится в разработке.)

Идя дальше, я обнаружил, что бэкэнд Postgres направляет Django для создания столбцов, использующих часовые пояса.

Нет, это дизайн Djangoрешение.PostgreSQL хранит только UTC;он не хранит часовой пояс и не сохраняет смещение.Часовой пояс концептуально похож на переменную окружения, которая применяется к меткам времени, когда они вставляются или выбираются для извлечения.

Из почтового архива разработчика django .,.

Ввиду отсутствия фактической поддержки часовых поясов в базе данных, любое действие, предпринятое django, может кому-то причинить неудобства и, вероятно, будет несовместимо с использованием той же базы данных без использования django.

Это большая проблема - исправление, которое может сделать базу данных несовместимой с другими языками или средами.Это абсолютный ограничитель шоу, где я работаю;многие языки программирования и структуры обращаются к базе данных.

SQLite, Microsoft Access и MySQL (тип данных datetime, а не временная метка) упоминаются в этом потоке как отсутствие поддержки часового пояса в базе данных.

3 голосов
/ 05 ноября 2017

Я думаю, у вас неверное предположение. PostgreSQL не хранит информацию о часовом поясе :

Для timestamp with time zone внутренне сохраненное значение всегда находится в UTC (Всемирное координированное время, традиционно известное как среднее время по Гринвичу, GMT). Входное значение с указанным явным часовым поясом преобразуется в UTC с использованием соответствующего смещения для этого часового пояса. Если во входной строке не указан часовой пояс, предполагается, что он находится в часовом поясе, указанном системным параметром TimeZone, и преобразуется в UTC с использованием смещения для часового пояса.

Таким образом, информация о часовом поясе потеряна . Но момент времени сохраняется .

Это означает, что когда вы получаете информацию о метке времени, какой бы часовой пояс вы ни находились в данный момент, всегда будет правильным. Для большинства приложений это именно то, что вам нужно.

0 голосов
/ 15 марта 2013

Тот факт, что Postgresql способен хранить временные метки вместе с часовым поясом, - это хорошо.Временная метка должна представлять точку во времени.Если вы читаете «15.03.2013 14:38:00», достаточно ли точно знать, какой момент времени представлен?Нет!Это может быть 14:38 в Нью-Йорке или 14:38 в Берлине, и это два разных момента времени.Поэтому на самом деле никогда не должно быть временных отметок без часовых поясов (они называются «наивными» датами), если только не подразумевается конкретный часовой пояс (например, UTC).

Тот факт, что Django создает временную метку с часовым поясом, поэтому хорошо вещь, на мой взгляд.Вы можете переопределить это поведение по умолчанию, написав свой собственный DatetimeField , но я бы не рекомендовал его, если у вас нет очень веской причины избавиться от часовых поясов в базе данных (потому что это нарушает некоторые другие устаревшие программы, дляпример).

Если вы используете Django <1.4, тогда код клиента postgresql предполагает, что все datetime находятся в часовом поясе вашей системы.Так, если часовой пояс вашего сервера django - Берлин, то «2013-03-15 14:38:00» будет интерпретироваться как 14:38 в часовом поясе Берлина, и вся эта информация будет храниться в базе данных.Если вы удалите информацию о часовом поясе, то у вас будут проблемы при <a href="http://en.wikipedia.org/wiki/Daylight_saving_time" rel="nofollow"> DST изменениях времени.Например, «2013-10-26 02:30:00» неоднозначно: это первое или второе появление 2:30?Если вы идете по этому пути, вы должны преобразовать все даты и время в UTC в своем коде Django и сохранить время в формате UTC в базе данных.

Если вы используете Django> = 1.4, то по умолчанию он учитывает часовой пояси ожидает, что у каждой даты и времени будет часовой пояс.Поскольку к сожалению, в python datetime по умолчанию не есть часовые пояса, вы должны использовать пакет pytz , чтобы убедиться, что каждое манипулируемое вами время и датой учитывает часовой пояс.

Документация Django о часовых поясах - очень хорошее чтение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...