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

使用Python+Lambda解压S3多层目录压缩包时报No Such Key错误

问题解决方案

你遇到的NoSuchKey错误和创建IO缓冲区的操作本身无关,该错误的核心含义是你传入的zip_key在指定S3存储桶中不存在。你观察到「仅含单个文件的压缩包运行正常、含多层目录的压缩包报错」,本质是两类压缩包的上传路径/文件名差异触发了S3事件通知的编码逻辑,和压缩包内部结构没有直接关联。

核心修复方案

S3事件通知返回的object.key默认是URL编码格式,如果你的压缩包文件名/上传路径包含空格、中文、特殊符号(甚至多层目录拼接时的特殊字符),会被编码为%XX格式,直接用编码后的key请求S3就会找不到对象。

修改代码如下:

  1. 首先导入URL解码模块
from urllib.parse import unquote_plus
  1. 修改zip_key的取值逻辑,增加解码步骤
bucketname = event["Records"][0]['s3']['bucket']['name']
# 对S3返回的原始key做URL解码
raw_zip_key = event["Records"][0]['s3']['object']['key']
zip_key = unquote_plus(raw_zip_key)
s3_uri = 's3://'+bucketname+'/'

辅助排查验证

  • 增加日志打印确认key正确性,在调用zip_obj.get()前添加打印逻辑:
    print(f"验证存储桶:{bucketname},验证压缩包key:{zip_key}")
    
    执行后到Lambda对应的CloudWatch日志组查看打印值,和S3控制台中对应压缩包的完整key对比,确保完全一致(S3 key大小写敏感)。
  • 确认Lambda执行角色的S3读权限覆盖了对应路径的zip文件,没有权限边界或存储桶策略拦截GetObject请求。

额外代码优化建议

针对你当前的解压逻辑,可补充两个优化点避免后续报错:

  1. 跳过压缩包内的目录项:z.namelist()会返回目录路径(结尾为/),直接上传空目录会抛出异常,可在循环中简化判断逻辑:
    for filename in z.namelist():
        # 跳过目录项和Mac系统生成的隐藏文件目录
        if filename.endswith('/') or '__MACOSX' in filename:
            continue
        s3_client.meta.client.upload_fileobj(z.open(filename),Bucket=bucketname,Key=f'output/{filename}')
    
  2. 大体积压缩包适配:当前逻辑是将整个压缩包加载到Lambda内存,若压缩包体积超过Lambda分配的内存会触发OOM,可修改为流式处理减少内存占用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 08:06:03