Redshift中PostgreSQL外部表时区信息丢失问题求助
在AWS Redshift中从外部表保留带时区信息的时间戳
问题场景
- PostgreSQL客户端时区设为KST时,查询结果为:
2024-01-25 23:59:59.000000 +09:00 - Redshift默认查询外部表时,返回结果丢失时区信息,转为UTC:
2024-01-25 23:59:59+00 - 将Redshift全局时区设为
'Asia/Seoul'后,时区信息保留,但时间值被转换,与原结果不一致:2024-01-26 08:59:59+09
解决方案
1. 确保外部表数据类型正确
外部表(如Redshift Spectrum基于S3的表)中,需将时间戳字段定义为带时区的类型(如TIMESTAMP WITH TIME ZONE,对应Parquet/Orc中的timestamp with timezone)。若原始数据存储为不带时区的TIMESTAMP,后续无法恢复时区信息。
2. 用AT TIME ZONE语法精准控制转换
避免依赖全局时区设置,在查询时显式指定时区转换,保留原始时间戳的时区偏移:
- 若外部表字段
ts_col为TIMESTAMP WITH TIME ZONE类型,要输出原始KST格式的时间戳:SELECT TO_CHAR(ts_col, 'YYYY-MM-DD HH24:MI:SS.US TZ') AS full_ts_with_tz FROM external_table; - 若外部表存储的是UTC时间(原始KST时间已转成UTC存储),要还原为原始KST时间戳:
-- 先将timestamptz转为UTC的timestamp,再转换为KST时区的带时区时间戳 SELECT (ts_col AT TIME ZONE 'UTC') AT TIME ZONE 'Asia/Seoul' AS original_kst_ts FROM external_table;
3. 创建外部表时指定时区解析规则(针对Spectrum)
若查询S3上的Parquet/Orc外部表,创建表时通过参数指定时区解析规则,确保读取时保留原始时区:
CREATE EXTERNAL TABLE external_table ( ts_col TIMESTAMP WITH TIME ZONE ) STORED AS PARQUET LOCATION 's3://your-bucket/path/' TBLPROPERTIES ( 'parquet.timestamp.type' = 'TIMESTAMP_WITH_TIME_ZONE', 'timezone' = 'Asia/Seoul' );
4. 避免全局时区修改的副作用
全局设置Redshift时区(SET TIME ZONE 'Asia/Seoul')会导致所有会话的TIMESTAMP WITH TIME ZONE数据自动转换为该时区显示,引发时间值变更。优先使用查询级别的显式转换,而非全局修改。
内容的提问来源于stack exchange,提问作者user23314066
相关产品推荐
相关产品推荐

