将数据从本地复制到 S3 到 Redshift 表时出现问题

Posted

技术标签:

【中文标题】将数据从本地复制到 S3 到 Redshift 表时出现问题【英文标题】:Issue while copying data from local to S3 to Redshift table 【发布时间】:2015-03-23 09:45:37 【问题描述】:

我编写了一个程序,它生成 csv 格式的数据,然后将该数据上传到 S3,最终将副本复制到 Redshift 表。这是代码

bucket2 = self.s3Conn.lookup('my-bucket')
    k = Key(bucket2)

    ## Delete existing
    key_del = bucket2.delete_key("test_file.csv")

    ## Create new key and upload file to s3
    k.Key = "test_file.csv"
    k.name = "test_file.csv"
    k.set_contents_from_filename('test_file.csv')

    ## Move file from S3 to redshift

    logging.info("\nFile Uploaded to S3 bucket\n")

    try:

        self.newCur.execute("Truncate test_file")

        self.newCur.execute("COPY test_file FROM 's3://my-bucket/test_file.csv' credentials 'aws_access_key_id=xxxxxx;aws_secret_access_key=xxxxxx DELIMITER ','; ")

    except psycopg2.DatabaseError, e:
        logging.exception("Database exception ")

文件有大约 13500 行和 10 列。 我验证了 redhshift 具有相同的列数和数据类型

但是,每次它在 13204 行之后中断,“stl_load_errors”表中的错误为“Delimited not found”。第 13204 行中的数据无关紧要,因为我还使用其他值更新了该行。

所以我检查了 S3 存储桶来检查我的 csv 文件。我下载了复制到 S3 存储桶的文件。我看到的是该文件没有完全复制。它通常会中断大约 811007 个字符。

之前我已经将较大的文件上传到 S3 没有任何问题。

知道为什么会这样吗?

【问题讨论】:

一些随机的想法:将boto更新到最新版本(sudo pip install boto --upgrade),它与行数或文件长度有关吗?您上传的较大文件是否使用相同的代码完成?,当您调用 set_contents_from_filename 时,它​​会返回写入的字节数——它们是否与您的预期大小或创建的实际文件的大小相匹配? 【参考方案1】:

感谢您的帮助。问题很简单。

我正在使用 file.write() 在本地磁盘上写入文件,然后将其复制到 S3。 所以在复制到 S3 之前,我需要使用file.close() CLOSE 文件,我没有这样做。

是的,这很愚蠢:)

【讨论】:

【参考方案2】:

如果在第 13204 行有 NULL 字节 0x00,您应该仔细观察。我已经看到字段中间的那些会导致不同类型的加载错误。要检查,您可以使用 NULL AS '\000' 选项绕过它们或使用十六进制编辑器来读取文件。请注意,普通编辑器可能不会显示空字节。

【讨论】:

【参考方案3】:

我在 Redshift CSV 上传脚本中采用了类似的方法。 您可以使用它来进行“健全性检查”或为您正在处理的脚本绘制性能基线。

试试CSV_Loader_For_Redshift。

脚本将:

压缩文件并将其上传到 S3 将您的数据附加到 Redshift 表中。

12Mb/50k 行文件的示例输出:

S3        | data.csv.gz | 100% 
Redshift  | test2       | DONE 
Time elapsed: 5.7 seconds

【讨论】:

以上是关于将数据从本地复制到 S3 到 Redshift 表时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

将数据从 Amazon S3 复制到 Redshift 并避免重复行

将数据从本地迁移到 AWS redshift

在 docker 容器超时中从 s3 复制到 Redshift

Node-Redshift 是不是支持复制命令(查询)将数据从 S3 加载到 Redshift?

将数据从 s3 复制到 redshift 时忽略所有无效记录

将文件从 s3 复制到 redshift 花费的时间太长