【问题标题】:How to rename multiple output files in S3 through Lambda如何通过 Lambda 重命名 S3 中的多个输出文件
【发布时间】:2021-06-05 15:15:01
【问题描述】:

如何重命名 S3 存储桶中的多个输出文件。作为一个例子,我正在使用

os.path.basename(keyprefix),

'w' 写入模式文件

abc_00000.csv.gz
abc_00001.csv.gz 

我想用命名约定重命名上述文件:

 abc_{today date in YYYYMMDD format}_00.csv.gz 
 abc_{today date in YYYYMMDD format}_01.csv.gz

以下是参考代码:

    import boto3
    import os
    from smart_open import open
    import gzip
    import csv
    import io
    def lambda_handler(event, context):
    dirpath = 'output/'
    bucket = 'export'
    key = 'export/_SUCCESS'

    if '_SUCCESS' in key:
    client = boto3.client('s3')
    response = client.list_objects_v2(Bucket=bucket,Prefix=os.path.dirname(key))
    for i in response['Contents']:
        keyprefix = i['Key']
        if 'part-' in keyprefix:
            with gzip.GzipFile(fileobj=client.get_object(Bucket=bucket,Key=keyprefix)['Body']) as gzipfile, open('s3://'+bucket + '/' + dirpath + os.path.basename(keyprefix),'w') as fout :
    writer = csv.writer(fout , delimiter=',')
                writer.writerow(['test1','test1','test3','test4','test5','test6','test7'])        
                for row in csv.reader(gzipfile.read().decode('utf-8').splitlines(), delimiter=',', quotechar='"'):
                    if row[5] == 'CDE':         
                        writer.writerow(row)

【问题讨论】:

  • 我建议看看S3 Batch Operations basics。在您的情况下,不确定重命名的规模是多少。进行批量操作的高效且干净的方式。
  • 嗨@samtoddler,谢谢。它最多10-15个文件。
  • 仅供参考,您无法在 S3 中重命名对象。您必须从旧密钥复制到新密钥,然后删除旧密钥。
  • 有什么方法可以在提供的 python 脚本中编写所需的命名约定?

标签: python python-3.x amazon-web-services amazon-s3 aws-lambda


【解决方案1】:

S3 Service Resource 提供更多灵活性。

复制文件后,我正在删除旧文件,如果您想保留,可以删除删除调用。

#!/usr/bin/env python3

import boto3
import os
from datetime import datetime
prefix = 'abc_'
new_prefix = f"{prefix}{datetime.today().strftime('%Y-%m-%d')}"
suffix = 'csv.gz'
bucket_name = 'mybucketname'

def lambda_handler(event, context):
    s3 = boto3.resource('s3')
    bucket = s3.Bucket(bucket_name)
    for obj in bucket.objects.all():
        key = obj.key
        path_part = os.path.dirname(key)
        filename = os.path.basename(key)
        copy_source = {
        'Bucket': bucket_name,
        'Key': key
        }
        if filename.startswith(prefix) and filename.endswith(suffix):
            new_key = f"{new_prefix}_{key.split('_')[1]}"
            full_key_with_path = os.path.join(path_part, new_key)
            destination_bucket = s3.Bucket(bucket_name)
            print(f'copying the object with new key : {full_key_with_path}')
            destination_bucket.copy(copy_source, full_key_with_path)
            print(f'deleting old key : {key}')
            s3.Object(bucket_name, key).delete()

❯❯ python3 s3rename.py 
copying the object with new key : myinventorylist/2021-02-07T00-00Z/abc_2021-03-07_00000.csv.gz
deleting old key : myinventorylist/2021-02-07T00-00Z/abc_00000.csv.gz
copying the object with new key : myinventorylist/2021-02-07T00-00Z/abc_2021-03-07_00001.csv.gz
deleting old key : myinventorylist/2021-02-07T00-00Z/abc_00001.csv.gz

【讨论】:

  • 感谢您的帮助。简单的问题:如何在我提供的代码中容纳您的代码?我是 Python 的初学者,所以想检查一下。
  • @Ram 我移动了代码以与 aws lambda 兼容,您基本上可以更改必要的值,例如 bucket_name 或者如果您也想调整后缀和前缀,而且在您的代码中看起来像也修改文件,我不确定你要写什么,你已经处理好了。我共享的代码只是将文件复制到您共享的命名标准并删除与给定前缀和后缀匹配的旧文件。
  • :谢谢,在我的代码中,如果是“CDE”,我将更改标题列名称并根据第 5 列过滤数据。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-23
  • 2021-02-14
  • 2017-12-02
  • 2018-06-12
  • 1970-01-01
  • 1970-01-01
  • 2022-11-13
相关资源
最近更新 更多