UNLOAD 使用包含引号和分隔符的数据

Posted

技术标签:

【中文标题】UNLOAD 使用包含引号和分隔符的数据【英文标题】:UNLOAD with data containing quotes and delimiters 【发布时间】:2020-09-17 16:59:08 【问题描述】:

输入表

Id | Text
----------------------
1  | Alok
2  | Alok,"Kumar",Singh

目标表

Id | Text
----------------------
0  | Vicky

问题/疑问

需要在 Redshift 中使用 UNLOAD 和 COPY 将行从 inpuTable 复制到 targetTable。怎么做?

Redshift 提供ADDQUOTESDELIMETER,如果数据不需要转义DELIMETER,这将很有帮助。我在 Redshift 中找不到转义 DELIMETER 标志。请建议如何在不编写添加引号的过程的情况下执行此操作。

尝试 1

UNLOAD ('select * from inputTable') TO 's3://bucket/key/unload_' manifest allowoverwrite FORMAT AS CSV DELIMITER ',' ESCAPE;
1,Alok
2,Alok,"Kumar",Singh,
COPY targetTable FROM 's3://bucket/key/unload_manifest' manifest FORMAT AS CSV QUOTE AS '\"' DELIMITER ','

COPY 命令加载数据失败。如何使用 UNLOAD 和 COPY 解决?

ERROR: ESCAPE is not supported for UNLOAD to CSV

【问题讨论】:

为什么要使用 UNLOAD 和 COPY 在表之间进行复制?为什么不直接通过 SQL INSERT 命令插入值? INSERT INTO targetTable SELECT * from inputTable 因为 inputTable 中的数据非常庞大,需要复制到 targetTable 并且据我了解 UNLOAD 和 COPY 是这里最快和有效的方法? @JohnRotenstein 不,执行批量 INSERT 会比卸载和加载更快。 @JohnRotenstein 非常感谢您让我知道这一点。我在哪里可以阅读文档和基准测试中两种方法的差异? 坦率地说,我不记得读过任何关于 UNLOAD 和 COPY 的建议。 Deep Copy 也有类似的情况,有时最好创建一个新表而不是插入到现有表中,但在您的情况下,这取决于每个表的大小。除非您在谈论数百万或数十亿或行,否则只需插入数据就可以了。但是...我强烈建议您测试这两种方法的性能,并根据您发现的结果做出选择。 【参考方案1】:

ESCAPEADDQUOTESREMOVEQUOTES 解决了这个问题。

UNLOAD ('select * from inputTable') TO 's3://bucket/key/unload_' manifest allowoverwrite ADDQUOTES ESCAPE DELIMITER ',';
COPY targetTable FROM 's3://bucket/key/unload_manifest' manifest REMOVEQUOTES ESCAPE DELIMITER ',';

这样就解决了。

【讨论】:

以上是关于UNLOAD 使用包含引号和分隔符的数据的主要内容,如果未能解决你的问题,请参考以下文章

从字符串中以空格分隔和引号括起来的元素获取数据字段

将带逗号的双引号作为分隔符从 S3 导入 Amazon Redshift

C#获取CSV文件内容对逗号和引号分隔的处理

如何使用 scanf 从用户输入中获取字符串( char * ),由双引号分隔并包含空格 [关闭]

Bigquery - 在 CSV(联合表)中处理双引号和管道字段分隔符

正则表达式拆分字符串,不包括可转义引号之间的分隔符