求助:AWS Lambda中Python写入S3失败(本地正常运行)
解决AWS Lambda中无法将文件保存到S3的问题
看起来你遇到的问题大概率和Lambda临时目录的使用逻辑或者不必要的本地文件操作有关,我来帮你一步步排查和解决:
优先推荐:直接上传Bytes到S3(跳过本地文件)
你提到response.content是bytes类型,其实完全不需要先保存到本地(包括Lambda的/tmp目录),直接用boto3把bytes数据上传到S3即可——这不仅能避免文件路径的问题,还能提升Lambda的执行效率。
示例代码如下:
import boto3 s3 = boto3.client('s3') def lambda_handler(event, context): # 假设你已经获取到了response.content的bytes数据 content_bytes = response.content bucket_name = 'transportation.manifests.parsed' s3_key = 'csv/your_file_name.csv' # 替换成你实际的文件名 # 直接上传bytes到S3 try: s3.put_object( Bucket=bucket_name, Key=s3_key, Body=content_bytes ) print("文件上传成功!") except Exception as e: print(f"上传失败:{str(e)}") raise e
如果必须使用/tmp目录:解决路径不存在的问题
如果你的业务逻辑确实需要先把文件写到/tmp,那报错[Errno 2] No such file or directory通常是因为你要写入的路径包含了未创建的子目录(比如/tmp/csv/out.csv,但/tmp/csv目录不存在)。Lambda默认只提供/tmp根目录,子目录需要手动创建。
解决代码示例:
import boto3 import os s3 = boto3.client('s3') def lambda_handler(event, context): content_bytes = response.content bucket_name = 'transportation.manifests.parsed' local_file_path = '/tmp/csv/your_file_name.csv' s3_key = 'csv/your_file_name.csv' # 先创建必要的目录,exist_ok=True避免目录已存在时报错 os.makedirs(os.path.dirname(local_file_path), exist_ok=True) # 写入文件到/tmp with open(local_file_path, 'wb') as f: f.write(content_bytes) # 上传到S3 try: s3.upload_file(local_file_path, bucket_name, s3_key) print("文件上传成功!") except Exception as e: print(f"上传失败:{str(e)}") raise e
最后别忘了检查Lambda的IAM权限
确认你的Lambda执行角色拥有s3:PutObject权限,目标资源需要覆盖arn:aws:s3:::transportation.manifests.parsed/csv/*(或者更宽泛的桶级权限)。参考权限策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::transportation.manifests.parsed/csv/*" } ] }
本地运行正常是因为你的本地系统会自动处理目录创建(或者你本地已经有对应的目录),但Lambda的/tmp是每次执行的干净环境,子目录不会自动存在——这就是核心差异点啦。
内容的提问来源于stack exchange,提问作者tskittles




