使用 UNLOAD 命令将 AWS Redshift 数据导出到 S3 时输出不正确

Posted

技术标签:

【中文标题】使用 UNLOAD 命令将 AWS Redshift 数据导出到 S3 时输出不正确【英文标题】:Incorrect output when exporting AWS Redshift data to S3 using UNLOAD command 【发布时间】:2018-04-21 17:38:55 【问题描述】:

我不是数据库专家,我刚刚开始探索 Redshift。我创建了一个集群并使用他们的示例脚本来填充表。我想将数据从 Redshift 复制到 Postgres。我首先想将数据导出到 S3,然后导入 Postgres。在我运行以下命令后,在我的 S3 存储桶中生成了一个文件:

UNLOAD ('select * from date')
TO 's3://sample-dwh-data/date_' credentials
'aws_access_key_id=******;aws_secret_access_key=*************'
PARALLEL OFF;

这是我用来在 Redshift 中创建 date 表的脚本:

create table date(
    dateid smallint not null distkey sortkey,
    caldate date not null,
    day character(3) not null,
    week smallint not null,
    month character(5) not null,
    qtr character(5) not null,
    year smallint not null,
    holiday boolean default('N'));

问题是,当我打开 S3 中存在的导出文件时,我看到每行的最后一列的值设置为 ft。导出文件的示例输出:

2070|2008-09-01|MO|36|SEP|3|2008|t
2071|2008-09-02|TU|36|SEP|3|2008|f

但是,如果我查询 Redshift 表,最后一列的值是 truefalse。那么,为什么UNLOAD 命令会修剪最后一列的值?

更新: @Yankee:当我运行以下命令时: 'SELECT dateid,caldate,day,week,month,qtr,year,CASE WHEN holiday = true THEN 'TRUE' ELSE 'FALSE' END AS holiday from date',我收到了这个错误:

An error occurred when executing the SQL command:
UNLOAD ('SELECT dateid,caldate,day,week,month,qtr,year,CASE WHEN holiday = true THEN 'TRUE' ELSE 'FALSE' END AS holiday from date')
TO 's3://sample-dwh-data/date_...

[Amazon](500310) Invalid operation: syntax error at or near "TRUE" 
Position: 87;

UNLOAD ('SELECT dateid,caldate,day,week,month,qtr,year,CASE WHEN holiday = true THEN 'TRUE' ELSE 'FALSE' END AS holiday from date')
                                                                                      ^                                                                                
1 statement failed.

【问题讨论】:

您为什么认为这是个问题? unload 命令使用 t 和 f 来表示布尔值。复制命令会接受这些作为有效值。 问题是我想将导出的数据加载到 Heroku 上运行的 Postgres 实例。我不确定这是否会将f 更改为falset 更改为true,同时将其导入另一个数据库(在我的情况下,Heroku Postgres)。此外,在布尔值的情况下,UNLOAD 操作修剪输出是否常见? 【参考方案1】:

您可以指定列名,而不是 SELECT * FROM DATE,然后您可以通过使用 CASE IF ELSE 条件自定义导出数据的方式。

SELECT dateid,caldate,day,week,CASE WHEN holiday = true THEN \'TRUE\' ELSE \'FALSE\' END AS holiday from date;

【讨论】:

抱歉回复延迟。请检查上面的更新部分。 @Technext 您可以尝试以下更改: 1. 删除 'TRUE' 和 'FALSE' 中的单引号,即 WHEN holiday = true THEN TRUE ELSE FALSE 或 2. 从 this 中,您应该转义单引号带反斜杠,这样就可以得到:WHEN holiday = true THEN \'TRUE\' ELSE \'FALSE\' END。这两个都应该工作。 感谢语法更正。该命令确实执行了,但是当我使用您的第一个建议时结果仍然相同。但是,尝试您的第二个建议就可以了。 :) 谢谢。我仍然想知道为什么 UNLOAD 不尊重实际值而是修剪它。 @Technext 太好了,很高兴它有帮助。我将编辑我的答案,请将其标记为已接受,因为它可以解决您的问题。 Here,您可以看到没有文档说明 Redshift 为何这样做。 感谢@Yankee 的链接! :)

以上是关于使用 UNLOAD 命令将 AWS Redshift 数据导出到 S3 时输出不正确的主要内容,如果未能解决你的问题,请参考以下文章

解密 Amazon Redshift CSV 转储

如何处理 AWS Redshift 卸载命令中的引用值?

无法使用 aws nodejs sdk 创建 Redshift 表

UNLOAD 命令是不是从 redshift 中删除或删除数据?

AWS 红移卸载附加时间戳

launchctl remove 和 unload 命令的区别