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

在 SQL redshift 中返回特定周的第一个日期(星期日)

从表中检索列名 -Redshift