在 Python 中从 S3 上的文件在 S3 上创建一个 zip 文件

Qui*_*ote 5 python amazon-s3 amazon-web-services boto3 aws-lambda

我正在尝试压缩 S3 存储桶上目录中保持相同目录结构的所有文件,并将该 zip 放在 S3 存储桶上。

使用 BytesIO 和 zipfile 将 zip 文件从 S3 存储桶解压缩到 S3 存储桶非常容易,但我不确定如何使用包含一百个文件的目录来执行此操作。

我发现此链接很有帮助,但该帖子适用于 Lambda Node。 使用 Lambda 节点从 S3 上的文件在 S3 上创建一个 zip 文件

for*_*aws 2

为了避免将各个对象下载到磁盘上,您需要流式传输每个前缀的对象(请记住:S3 使用层次结构),在本地保存 zip,将其上传到 S3,然后删除。这是我将使用的代码(并在 AWS 中成功测试):

import boto3
import io
import zipfile
import os

s3 = boto3.client('s3')

def zip_files(bucket_name, prefix):
    # List all objects in the bucket with the specified prefix
    response = s3.list_objects_v2(Bucket=bucket_name, Prefix=prefix)


    # Create a BytesIO object to store the compressed data
    zip_buffer = io.BytesIO()

    for obj in response.get('Contents', []):
        s3_object = s3.get_object(Bucket=bucket_name, Key=obj['Key'])

        # Use the ZipFile module to write the contents of the S3 object to the zip stream
        with zipfile.ZipFile(zip_buffer, 'w') as zip_file:
            # Write the contents of the S3 object to the zip file
            zip_file.writestr(obj['Key'], s3_object['Body'].read())

        # Save the zip file to disk
        with open(f'{prefix.rstrip("/")}.zip', 'wb') as f:
            f.write(zip_buffer.getvalue())

    # Upload the compressed data to the S3 bucket and delete
    zip_buffer.seek(0)
    s3.put_object(Bucket=bucket_name, Key=f'{prefix}{prefix.rstrip("/")}.zip', Body=zip_buffer)
    os.remove(f'{prefix.rstrip("/")}.zip')

bucket = 'foobucket'
folders = ['foo/', 'bar/', 'baz/']
for folder in folders:
    zip_files(bucket, folder)
Run Code Online (Sandbox Code Playgroud)

您没有提供任何 Python 代码来表明您遇到了与您链接的 Lambda 节点中描述的相同的内存限制,因此我假设这不是一个大问题。无论哪种方式,os.remove随着流程的继续,都应该保持轻量级。

另外:如果您在 Lambda 函数中运行此逻辑,则必须对其进行调整以适应 Lambda 所需的格式。

显然,根据您的需要添加日志记录和错误处理。

希望这可以帮助!