【问题标题】:Create a zip file on S3 from CSV files on S3 using Lambda使用 Lambda 从 S3 上的 CSV 文件在 S3 上创建一个 zip 文件
【发布时间】:2021-04-05 00:57:05
【问题描述】:

每天在我的 S3 存储桶中生成大约 60 个 CSV 文件。每个文件的平均大小约为 500MB。我想通过 lambda 函数即时压缩所有这些文件(无需在 Lambda 执行中下载文件)并将这些压缩文件上传到另一个 s3 存储桶。我遇到了这些解决方案12,但我在实施中仍然遇到问题。现在,我正在尝试将 CSV 文件数据流式传输到压缩文件中(此 zip 文件正在 Lambda tmp 目录中创建),然后在 s3 上上传。但我在写入 zip 文件时收到此错误消息: [Errno 36] File name too long

这是我的测试 Lambda 函数,我只是尝试使用一个文件,但实际上我需要单独压缩 50-60 个 CSV 文件:

import boto3
import zipfile


def lambda_handler(event, context):
    s3 = boto3.resource('s3')
    iterator = s3.Object('bucket-name', 'file-name').get()['Body'].iter_lines()
    my_zip = zipfile.ZipFile('/tmp/test.zip', 'w')
    for line in iterator:
        my_zip.write(line)
    
    s3_resource.meta.client.upload_fileobj(file-name, "another-bucket-name", "object-name") 

另外,有没有一种方法可以让我从我的 CSV 文件中流式传输数据,将其压缩并上传到另一个 s3 存储桶,而无需在 Lambda 内存上实际保存完整的 zip 文件?

【问题讨论】:

  • 是什么样的数据?如果它们是 CSV 或 Athena 可以读取的其他数据格式,我使用了预定的 Athena-Query 来压缩文件,但解决方案有点奇怪 ;-)
  • @Maurice 数据为 CSV 格式。您的解决方案是什么?

标签: python amazon-s3 aws-lambda boto3 zipfile


【解决方案1】:

经过大量的研究和试验,我能够让它发挥作用。我使用smart_open 库来解决我的问题,并设法在我的 Lambda 中压缩 550MB 文件,而内存使用量仅为 150MB。要使用外部库,我必须在 Lambda 中使用 Layers。这是我的代码:

from smart_open import open, register_compressor
import lzma, os


def lambda_handler(event, context):
    with open('s3://bucket-name-where-large-file/file-key-name') as fin:
        with open('s3://bucket-name-to-put-zip-file/zip-file-key-name', 'w') as fout:
            for line in fin:
                fout.write(line)

请注意,smart_open 支持.gz.bz2 文件压缩。如果你想压缩其他格式的文件,你可以使用这个库的register_compressor方法创建你自己的压缩器。

【讨论】:

    猜你喜欢
    • 2016-12-02
    • 2019-11-12
    • 1970-01-01
    • 2016-11-10
    • 2023-01-16
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 2021-01-13
    相关资源
    最近更新 更多