从 Amazon Redshift UNLOAD 创建对 RFC-4180 友好的 CSV 文件的最佳方法是啥?

Posted

技术标签:

【中文标题】从 Amazon Redshift UNLOAD 创建对 RFC-4180 友好的 CSV 文件的最佳方法是啥?【英文标题】:What's the best way to create RFC-4180-friendly CSV files from Amazon Redshift UNLOAD?从 Amazon Redshift UNLOAD 创建对 RFC-4180 友好的 CSV 文件的最佳方法是什么? 【发布时间】:2016-01-28 18:37:38 【问题描述】:

在使用 UNLOAD 时,Amazon Redshift 并没有真正的 CSV 选项(例如,类似于 PostgreSQL 的 COPY 命令中的 WITH CSV)。

如果您使用ESCAPE 选项,Redshift 会使用\ 转义双引号。例如,Excel 不知道如何处理该斜线。根据 RFC-4180,它确实应该使用双引号

如果使用双引号将字段括起来,则使用双引号 出现在字段内必须通过在它前面加上 另一个双引号。例如:

"aaa","b""bb","ccc"

Sooo... 引号会破坏导出,除非我们能想办法让 Redshift 正确地转义它们。

给定以下数据:

# select * from unload_test;
                 test_field                 | test_field_number
 --------------------------------------------+-------------------
 "No," she said, "that's not how we do it." |                 5
 Hi! This is a test, yo.                    |                 5
如果我们使用ESCAPE 但不使用ADDQUOTES,Excel 等人将继续拆分所有逗号上的列,包括“转义”的逗号 (\,)。 Example 如果我们同时使用ESCAPEADDQUOTES,您会得到您在初始问题示例中看到的结果。 如果我们使用ADDQUOTES 但我们不使用ESCAPE,那么它将在数据中的双引号中中断。 Example 当然,如果我们不使用其中任何一个,我们也会使用逗号和可能的引号来换行。

是否有可用的解决方法来同时容纳数据中的引号和逗号?

【问题讨论】:

从文档来看,它似乎也不够聪明,只能在需要引号时添加引号。 在一个完美的世界里,你会添加一个RFC4180 子句,它就会开始遵守标准。 【参考方案1】:

缩放解决方案是使用 perl / sed 处理内容并将其转换为适当的 CSV。

这些标志是必需的:DELIMITER ',' ADDQUOTES ESCAPE

aws s3 cp s3://mybucket/non_csv/part_0000 - | \
# Unescapes \" into "" but only when odd number of backslashes are found backwards
perl -pe 's/((?<![\\])(\\\\)*)\\"/\1""/g' | \
# Removes \ but only when odd number of backslashes are found backwards
perl -pe 's/((?<![\\])(\\\\)*)\\/\1/g' | \
# Unescapes \\ into \
sed -e 's/\\\\/\\/g' | \
aws s3 cp - s3://mybucket/csv/part_0000

我在真实嘈杂的数据上使用各种边缘情况对此进行了测试,它产生了正确的结果。所有的反斜杠都被删除了,因为除了 " -> "" 并添加了引号之外,什么都不能转义。

示例测试:

$ echo '"","\"\"Hi\\\\\"","\\\\","\<tab>"' | perl -pe 's/((?<![\\])(\\\\)*)\\"/\1""/g' | perl -pe 's/((?<![\\])(\\\\)*)\\/\1/g' | sed -e 's/\\\\/\\/g'

输出:

"","""""Hi\\""","\\","<tab>"

需要 PERL 或其他高级正则表达式引擎才能进行正确的后视。

性能不是问题,因为我使用的是网络带宽而不是 CPU。但是,可以使用 GNU 并行处理一次处理所有输出文件。

但是,我没有测试aws s3 cp 部分,因为我使用另一个工具将 S3 内容导入 STDIN。

干杯!

【讨论】:

以上是关于从 Amazon Redshift UNLOAD 创建对 RFC-4180 友好的 CSV 文件的最佳方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

解密 Amazon Redshift CSV 转储

Redshift UNLOAD 语句在 19 分钟后被取消

如何使用 aws unload 命令将数据从 AWS Redshift 卸载到 s3?

Amazon Redshift - 卸载到 S3 - 动态 S3 文件名

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

Redshift 中的 Unload 命令语法错误