将 Postgres TIMESTAMP 转换为 TIMESTAMPTZ

GTF*_*GTF 12 postgresql migration datatypes timezone

我有一个在 Postgres 上运行的大小合适(约 50k 行)的时间序列数据库,还有一些其他结构化数据(在另一个数据库实例中)要小得多。

愚蠢的是,当我最初设计这个东西时,我把所有的字段都作为TIMESTAMP WITHOUT TIME ZONE,现在我用恼人的时区相关的错误来支付它。我希望一切都是明确的,所以想将字段转换为TIMESTAMP WITH TIME ZONE. 我意识到这不会存储额外的信息,并且我所有的时间戳都已经在 UTC 中,所以迁移应该是微不足道的,但我想知道是否有任何复杂的事情/潜在的绊倒块会证明有问题(这是一个生产客户依赖它的数据库)?

Erw*_*ter 18

请注意,在转换过程中应用了正确的时区(在您的情况下为 UTC)。如果您对此不明确,则假定当前会话的时区 - 通常不是UTC。

ALTER TABLE tbl ALTER ts_column TYPE timestamptz USING ts_column AT TIME ZONE 'UTC';
Run Code Online (Sandbox Code Playgroud)

也检查一个可能的列默认值。任何处理数据类型timestamp(如LOCALTIMESTAMPnow()::timestamp)的表达式都会遇到同样的问题。改变:

ALTER TABLE tbl ALTER ts_column SET DEFAULT now();  -- or current_timestamp
Run Code Online (Sandbox Code Playgroud)

显然,写入表的语句timestamptz现在也需要使用- 或者您有另一个与 type 自动转换相同问题的实例timestamp [without time zone]

由于这是一个生产数据库,最好在单个事务中完成所有操作以避免竞争条件 - 甚至是单个语句:

ALTER TABLE tbl
  ALTER ts_column TYPE timestamptz USING ts_column AT TIME ZONE 'UTC'
, ALTER ts_column SET DEFAULT now();
Run Code Online (Sandbox Code Playgroud)

基本: