hek*_*ran 5 python django postgresql timezone datetime
我认为Django创建了与时区无关的日期时间列,但是当我查看我的Postgres表时,我看到记录的值有时区信息.
更进一步,我发现Postgres后端指示Django创建使用时区的列.
来自django/db/backends/postgresql/creation.py:
data_types = {
...
'DateTimeField': 'timestamp with time zone',
...
Run Code Online (Sandbox Code Playgroud)
架构显示已创建的列被指定为"带时区的时间戳".
CREATE TABLE notification_notice
(
...
created timestamp with time zone NOT NULL,
...
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
这就是我的表格.创建的列的时区对其时区具有"-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)
Run Code Online (Sandbox Code Playgroud)
问题:
Django不会对时区提供免提政策吗?
为什么Postgres后端为models.DateTimeField使用时区?这是Postgres要求的吗?
有没有办法强制Django在Postgres中创建不使用时区的时间戳列?
Mik*_*ll' 16
坏消息是问题的根源在于Python的日期时间实现.
坏消息是该票在2006年开业.
好消息是,最近的提案更有用,并且似乎正在开发中.包含提案的主题很长,但信息很丰富.
坏消息是该提案归结为"这真是一团糟".(仍在进行中.)
更进一步,我发现Postgres后端指示Django创建使用时区的列.
不,那是Django的设计决定.PostgreSQL仅存储UTC; 它不存储时区,也不存储偏移量.时区在概念上类似于环境变量,它在插入或选择用于检索时应用于时间戳.
来自django开发人员的邮件存档...
在数据库中没有实际时区支持的情况下,django采取的任何操作都会给某些人带来不便,并且可能与非django使用相同的数据库不兼容.
这是一个大问题 - 可能使数据库与其他语言或框架不兼容的修复.那是我工作的绝对表演者; 许多编程语言和框架访问数据库.
SQLite,Microsoft Access和MySQL(日期时间数据类型,而不是时间戳)在该线程中被引用为缺少数据库中的时区支持.
我认为你的假设是错误的。PostgreSQL不存储时区信息:
对于
timestamp with time zone,内部存储的值始终采用 UTC(通用协调时间,传统上称为格林威治标准时间,GMT)。指定了显式时区的输入值将使用该时区的适当偏移量转换为 UTC。如果输入字符串中未指定时区,则假定其处于系统 TimeZone 参数指示的时区,并使用时区的偏移量将其转换为 UTC。
所以实际上时区信息丢失了。但那一瞬间的时间却被保留了下来。
这意味着当您获取时间戳信息时,无论您或您的服务器当前位于哪个时区,都将始终是正确的。对于大多数应用程序来说,这正是您想要的。