使用默认分隔符“|”将~~ 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命令参数,这将有所帮助。
答案 0 :(得分:2)
如果您可以将此数据加载到其他表中一次,然后将其拆分到其他表中,这就是您可以做的 -
示例 - 假设您的数据有3列和2个管道,但其中一个管道有额外的管道。
然后用" |"将它卸载到S3。分隔符。
使用您确定不会出现在数据中的分隔符将已卸载的数据复制到此表中,例如\ t或\ 001(^ A)
对于除熟食店之外没有额外PIPES的行 - 插入新表。
查询应该是这样的 -
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数量。
||
是连接
如果您有任何问题,请与我们联系。
答案 1 :(得分:2)
你必须告诉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 :(得分:1)
创建另一个卸载:
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 '|';
您的卸载数据会在每个列值周围显示引号,如果它在引号中,则不会将管道视为分隔符。