从 S3 重新加载已卸载的表数据
Posted
技术标签:
【中文标题】从 S3 重新加载已卸载的表数据【英文标题】:Reloading unloaded table data from S3 【发布时间】:2016-01-06 15:52:50 【问题描述】:使用默认分隔符“|”将 ~500 gig 表卸载到 S3。该命令看起来像这样......
UNLOAD ('select * from some_table')
TO 's3://some-path/unloaded-tables/some-table/'
CREDENTIALS 'aws_access_key_id=xyz; aws_secret_access_key=abc'
MANIFEST;
我正在尝试使用如下命令将此数据重新加载回 some_table..
COPY some_table
FROM 's3://some-path/unloaded-tables/some-table/manifest'
CREDENTIALS 'aws_access_key_id=xyz; aws_secret_access_key=abc'
MANIFEST
DELIMITER '|';
对数据的一个子集进行了测试,以确保它是可重新加载的。然而,事实证明数据集中的一列可以包含一个管道(大约 %20 的记录似乎)。测试集中没有这样的数据。
现在尝试加载数据时,无法正确解析包含管道的记录。
我会惊讶地发现,UNLOAD 命令在卸载时并未转义记录中的分隔符,但也许这太天真了。
除了一些从 s3 下载每个文件并尝试手动解决问题的英雄程序之外,我有什么想法可以解决这个问题吗?我祈祷有一个神奇的 COPY 命令参数可以在这里提供帮助。
【问题讨论】:
如果您好奇,我能够恢复最初生成表的原始日志级别数据,并在此基础上重新生成表。 【参考方案1】:您必须告诉 Redshift 在卸载和复制命令中显式转义分隔符,并将所有字段括在引号中。
UNLOAD ('statement')
TO 's3://bucket'
CREDENTIALS 'aws_access_key_id=...;aws_secret_access_key=...'
GZIP
DELIMITER as '|'
ESCAPE ADDQUOTES ALLOWOVERWRITE;
然后复制
COPY table
FROM 's3path'
CREDENTIALS 'credentials'
GZIP REMOVEQUOTES ESCAPE DELIMITER '|'
FILLRECORD EMPTYASNULL BLANKSASNULL TIMEFORMAT 'auto'
COMPUPDATE off STATUPDATE off;
【讨论】:
谢谢,我现在明白了。【参考方案2】:如果您可以一次将该数据加载到其他表中,然后将其拆分到其他表中,这就是您可以做的 -
示例 - 假设您的数据有 3 列和 2 个管道,但其中一个有一个额外的管道。 然后你用“|”将它卸载到 S3分隔符。
使用单列和长度 varchar(max) 创建一个表 (T1)
将已卸载的数据复制到此表中,并使用您确定不会出现在数据中的分隔符 - 例如 \t 或 \001 (^A)
这是表格中数据的样子 -
创建具有所需列数和数据类型的新表 (T2)。
对于除了分隔符之外没有额外管道的行 - 插入到您的新表中。
查询应该是这样的 -
insert into T2
select split_part(X,"|",1),
split_part(X,"|",2),
split_part(X,"|",3)
from T1
where len(X) - len(replace(X,"|","")) = 3;
对于具有除定界符以外的 PIPE 的行,将拆分合并为一个并插入到 T2 中。
insert into T2
select split_part(X,"|",1),
split_part(X,"|",2),
split_part(X,"|",3) || split_part(X,"|",4)
from T1
where len(X) - len(replace(X,"|","")) = 4;
注意:
len(X) - len(replace(X,"|","")) = 3;
显示单元格中的 PIPE 数量。
||
是串联
如果您有任何问题,请告诉我。
【讨论】:
【参考方案3】:创建另一个卸载:
UNLOAD ('select * from some_table')
TO 's3://some-path/unloaded-tables/some-table/'
CREDENTIALS 'aws_access_key_id=xyz; aws_secret_access_key=abc'
DELIMITER '|' ADDQUOTES;
您的copy
命令将如下所示:
COPY some_table
FROM 's3://some-path/unloaded-tables/some-table/manifest'
CREDENTIALS 'aws_access_key_id=xyz; aws_secret_access_key=abc'
REMOVEQUOTES
DELIMITER '|';
您卸载的数据将在每个列值周围加上引号,如果它在引号中,它将不会将管道视为分隔符。
【讨论】:
谢谢,但不幸的是,第一次卸载后表格被截断了。以上是关于从 S3 重新加载已卸载的表数据的主要内容,如果未能解决你的问题,请参考以下文章
使用 Airflow 将数据从 Redshift 卸载到 S3
将数据从 Amazon redshift 卸载到 Amazon s3