将压缩文件保存到 s3 并加载到 Athena

Save compressed files into s3 and load in Athena

你好,我正在编写一些程序,它将写入一些文件(当时有更多进程),如:

with gzip.open('filename.gz', 'a') as f:
    f.write(json.dumps(some dictionary) + '\n')
    f.flush()

写完后我上传文件:

s3.meta.client(filename, bucket, destination, filename without .gz)

我想从 Athena 查询数据,在 MSCK REPAIR 之后一切似乎都很好,但是当我尝试 select 数据时,我的行是空的。有谁知道我做错了什么?

编辑:我的错误。我忘记将 ContentType 参数添加到 'text/plain'

Athena 检测具有适当文件扩展名的文件压缩格式。

因此,如果您上传 GZIP 文件,但删除了“.gz”部分(正如我从您的 "s3.meta.client(filename, bucket, destination, filename without .gz)" 语句中猜测的那样),SerDe 无法读取信息。

如果您将文件重命名为 filename.gz,Athena 应该可以读取您的文件。

我建议你把问题分成几个部分。

首先,创建一个未压缩的 JSON 文件。将其存储在 Amazon S3 中,然后使用 Athena 进行查询。

一旦成功,从命令行(而不是以编程方式)手动 gzip 文件,将文件放入 S3 并使用 Athena 查询它。

如果可行,使用您的代码以编程方式对其进行 gzip 压缩,然后重试。

如果对单个文件有效,请尝试对多个文件

以上所有内容都可以在 Athena 中使用相同的命令进行测试——您只需替换源文件即可。

这样一来,您就可以知道流程的哪一部分让雅典娜心烦意乱,而不会混淆潜在的原因。

我已经通过首先在本地保存更大的文件块而不是 gzip 来解决问题。我重复这个过程,但附加到 gzip 文件。读到添加更大的文本块比逐行添加更好

对于上传,我使用 boto3.transfet.upload_file 和 extra_args={'ContentEncoding': 'gzip', 'ContentType': 'text/plain'}

我第一次忘记添加 ContetType,所以 s3 以不同的方式保存它们,Athena 给了我错误,说我的 JSON 格式不正确。