Redshift DEFAULT GETDATE() 处理 INSERT 但不是 COPY
Posted
技术标签:
【中文标题】Redshift DEFAULT GETDATE() 处理 INSERT 但不是 COPY【英文标题】:Redshift DEFAULT GETDATE() working on INSERT but not COPY 【发布时间】:2016-07-27 17:38:19 【问题描述】:我的 Redshift 表中有一个带有默认约束的列,以便为其填充当前时间戳。
CREATE TABLE test_table(
...
etl_date_time timestamp DEFAULT GETDATE(),
...
);
这在 INSERTS 上按预期工作,但是当从 S3 复制没有此列的键的 json 文件时,我仍然得到空值
COPY test_table FROM 's3://bucket/test_file.json'
CREDENTIALS '...' FORMAT AS JSON 'auto';
// There shouldn't be any NULLs here, but there are
select count(*) from test_table where etl_date_time is null;
我也尝试在源 JSON 中为键设置一个空值,但这也会导致表中的值为空。
...
"etl_date_time": null,
...
【问题讨论】:
【参考方案1】:如果该字段始终为 NULL
,请考虑从 S3 的文件中完全省略它。 COPY
让您指定要复制的列,并将用它们的 DEFAULT
值填充缺失的列。
所以对于文件data.json
:
"col1":"r1_val1", "col3":"r1_val2"
"col1":"r2_val1", "col3":"r2_val2"
以及表定义:
create table _test (
col1 varchar(20)
, col2 timestamp default getdate()
, col3 varchar(20)
);
具体的列名
COPY
命令具有明确的列名
copy _test(col1,col3) from 's3://bucket/data.json' format as json 'auto'
会产生以下结果:
db=# select * from _test;
col1 | col2 | col3
---------+---------------------+---------
r1_val1 | 2016-07-27 18:27:08 | r1_val2
r2_val1 | 2016-07-27 18:27:08 | r2_val2
(2 rows)
省略的列名
如果省略列名,
copy _test from 's3://bucket/data.json' format as json 'auto'
永远不会使用DEFAULT
,而是插入NULL
:
db=# select * from _test;
col1 | col2 | col3
---------+---------------------+---------
r1_val1 | | r1_val2
r2_val1 | | r2_val2
(2 rows)
【讨论】:
对,我正在阅读的是,使用 JSON,您所描述的列映射应该根据 S3 文件中的键自动发生:docs.aws.amazon.com/redshift/latest/dg/… 是的。关键是从您的 JSON 中省略字段etl_date_time
。一旦它出现,它的DEFAULT
值显然不会被使用。
明白了……原来文件中没有 etl_date_time 键,我得到了这些结果。之后我只尝试添加具有空值的键
我已经编辑了我的原始回复。我希望这能澄清我想说的话。
这很有效 - 感谢您提供特定的 JSON 示例。缺少键似乎是 DEFAULT 的完美案例,所以这很奇怪以上是关于Redshift DEFAULT GETDATE() 处理 INSERT 但不是 COPY的主要内容,如果未能解决你的问题,请参考以下文章
在 Redshift 中将日期时间列格式化为 ISO 日期时间
sqlserver 中server 函数GETDATE(),DEFAULT用法
在 REDSHIFT 中的 ALTER 语句中连接字符串(语法错误)
从 parquet 文件将具有默认值的数据加载到 Redshift