You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

S3 Bucket中Lambda复制重命名文件报错:无效存储桶名称

解决S3复制文件时的「无效存储桶名称」错误

问题场景

我正在编写Lambda函数测试Athena表,功能已正常运行。现在需要重命名ResultConfiguration生成的输出文件,由于S3无法直接重命名,打算通过复制后删除原文件实现,但执行时一直提示「无效存储桶名称」错误。

相关代码

def copy_delete_output_results(query_id, table_name):
    oldCsvFileLocation = output + query_id + '.csv'
    newOutputLocation = output + table_name
    newFileName = table_name + '.csv'
    s3.Object(newOutputLocation,newFileName).copy_from(CopySource=oldCsvFileLocation)
    s3.Object(output,oldCsvFileLocation).delete()


# 变量示例
oldCsvFileLocation = 's3://ab-binaries-bucket-devtest/test/testQueryResults/1d8ab6ce-eda0-435f-93c3-2baa6fec8abd.csv'
newOutputLocation = 's3://ab-binaries-bucket-devtest/test/testQueryResults/dsm_abc_dns'
newFileName = 'dsm_abc_dns.csv'

报错信息

无效存储桶名称 "s3://ab-binaries-bucket-devtest/test/testQueryResults/dsm_abc_dns":存储桶名称必须匹配正则表达式 "^[a-zA-Z0-9.-_]{1,255}$",或者匹配ARN格式的正则表达式 "arn:(aws).*:(s3|s3-object-lambda):[a-z-0-9]*:[0-9]{12}:accesspoint[/:][a-zA-Z0-9-.]{1,63}$|arn:(aws).*:s3-outposts:[a-z-0-9]+:[0-9]{12}:outpost[/:][a-zA-Z0-9-]{1,63}[/:]accesspoint[/:][a-zA-Z0-9-]{1,63}$"

问题原因

核心错误是boto3的s3.Object()参数使用错误:

  • s3.Object()的第一个参数要求是纯存储桶名称(比如ab-binaries-bucket-devtest),第二个参数是文件的完整键(桶内路径+文件名)
  • 你传入的是完整的S3路径(包含s3://前缀和桶内子路径),导致boto3把整个路径当成了桶名,自然不符合桶名的正则规则
  • 另外,copy_from的参数格式也需要注意,虽然支持字符串格式,但要确保路径拆分正确

修正后的代码

方式1:直接指定桶名和基础路径

def copy_delete_output_results(query_id, table_name):
    # 明确指定存储桶名称和桶内基础路径
    bucket_name = 'ab-binaries-bucket-devtest'
    base_key = 'test/testQueryResults/'
    
    # 构建原文件和新文件的完整键
    old_file_key = base_key + query_id + '.csv'
    new_file_key = base_key + table_name + '.csv'
    
    # 复制文件:第一个参数是桶名,第二个是新文件的键
    s3.Object(bucket_name, new_file_key).copy_from(
        CopySource={'Bucket': bucket_name, 'Key': old_file_key}
    )
    # 删除原文件
    s3.Object(bucket_name, old_file_key).delete()

方式2:自动拆分完整S3路径(更灵活)

如果output变量是完整的s3://ab-binaries-bucket-devtest/test/testQueryResults/,可以通过字符串处理自动拆分桶名和路径:

def copy_delete_output_results(query_id, table_name):
    # 拆分S3路径,提取桶名和基础路径
    output_clean = output.strip().replace('s3://', '')
    bucket_name, base_key = output_clean.split('/', 1) if '/' in output_clean else (output_clean, '')
    
    # 确保基础路径末尾带斜杠,避免拼接时出错
    if base_key and not base_key.endswith('/'):
        base_key += '/'
    
    old_file_key = base_key + query_id + '.csv'
    new_file_key = base_key + table_name + '.csv'
    
    # 使用字符串格式的CopySource也可以
    s3.Object(bucket_name, new_file_key).copy_from(
        CopySource=f's3://{bucket_name}/{old_file_key}'
    )
    s3.Object(bucket_name, old_file_key).delete()

关键注意点

  • 永远不要把完整的S3 URL传给s3.Object()的第一个参数,必须单独传入纯桶名
  • CopySource支持两种格式:字典格式{'Bucket': '桶名', 'Key': '文件键'}(更清晰),或者字符串格式s3://桶名/文件键
  • 处理路径时注意末尾的斜杠,避免拼接后出现test/testQueryResults//xxx.csv这类无效路径

内容的提问来源于stack exchange,提问作者na2193

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 14:18:26