S3同桶文件迁移问题:Lambda实现文件移至桶根目录
S3文件迁移Lambda函数修复方案
问题场景
我们在名为
aftoem-resolver-group-data-1的S3桶中有如下文件结构:aftoem-resolver-group-data-1 |- 2023-09-25 // 日期文件夹 |- {AWS Glue生成的随机字符串}.csv预期效果是将日期文件夹内的CSV文件复制到桶根目录(重命名为
resolver_group-2023-09-25.csv),然后删除该日期文件夹及其中的文件,但当前Lambda运行后,文件被复制到了新的子文件夹中,未达到预期。
错误原因分析
- 错误1:目标键生成逻辑错误:原代码中
key[3:].partition("%")[0]的处理完全不符合需求,会把源文件的路径(包含斜杠)带入目标文件名,导致文件被写入子文件夹而非根目录。正确做法是从源文件路径中提取日期部分(文件夹名)。 - 错误2:冗余且错误的路径处理:原代码调用
list_objects_v2并使用response["Prefix"]作为复制源,完全没必要——事件中的key已经是源文件的完整路径,直接使用即可。 - 错误3:缺失删除逻辑:原代码没有实现复制完成后删除源文件夹及文件的步骤。
修正后的完整代码
import boto3 import botocore import logging logger = logging.getLogger() logger.setLevel(logging.INFO) s3_client = boto3.client('s3') def lambda_handler(event, context): logger.info("触发S3文件处理流程") # 从事件中提取源桶和源文件路径 source_bucket = event['Records'][0]['s3']['bucket']['name'] source_key = event['Records'][0]['s3']['object']['key'] logger.info(f"源桶: {source_bucket}, 源文件路径: {source_key}") # 提取日期部分(文件夹名):拆分路径,取第一个部分 date_folder = source_key.split('/')[0] # 生成目标文件名:根目录下的resolver_group-日期.csv target_key = f"resolver_group-{date_folder}.csv" logger.info(f"目标文件路径: {target_key}") try: # 复制源文件到目标路径 s3_client.copy_object( Bucket=source_bucket, CopySource={'Bucket': source_bucket, 'Key': source_key}, Key=target_key ) logger.info("文件复制完成") # 删除源文件和日期文件夹(S3中文件夹是虚拟的,删除所有前缀为日期的对象即可) response = s3_client.list_objects_v2(Bucket=source_bucket, Prefix=f"{date_folder}/") if 'Contents' in response: # 批量删除对象 delete_keys = [{'Key': obj['Key']} for obj in response['Contents']] s3_client.delete_objects( Bucket=source_bucket, Delete={'Objects': delete_keys} ) logger.info(f"已删除日期文件夹 {date_folder} 及其中的文件") except botocore.exceptions.ClientError as error: logger.error(f"操作失败: {error}") raise except botocore.exceptions.ParamValidationError as error: logger.error(f"参数错误: {error}") raise return {"status": "success", "message": "文件迁移完成"}
代码说明
- 目标路径生成:通过
source_key.split('/')[0]精准提取日期文件夹名,确保目标文件直接存放在桶根目录,无多余子路径。 - 简化复制逻辑:直接使用事件提供的完整源文件路径,避免冗余的list接口调用。
- 完整删除流程:通过列出日期文件夹下所有对象并批量删除,实现S3中“删除文件夹”的效果(S3无真实文件夹,删除所有前缀匹配的对象即可)。
- 优化异常处理:捕获异常后直接抛出,确保Lambda能正确上报错误状态,便于排查问题。
内容的提问来源于stack exchange,提问作者frp farhan
相关产品推荐
相关产品推荐

