AWS Lambda使用tempfile将字符串写入CSV上传S3报错如何解决
报错原因
- 核心错误是对
tempfile.TemporaryFile的用法错误:tempfile.TemporaryFile()的返回值本身就是可直接读写的文件类对象,不是本地文件路径字符串,不需要再调用open()去打开它,给open()传文件对象自然会触发类型不匹配的报错。 - 同时存在3个隐藏问题:
- 代码头部缺少
os、io、openpyxl的导入声明,运行时会触发模块未找到错误 s3.put_object()的调用参数错误,文件内容需要传给Body参数,不能直接把文件对象作为第一个位置参数传入- 拼接完的CSV字符串直接写入即可,不需要逐字符遍历写入,属于冗余操作
- 代码头部缺少
可行修复方案
你可以根据场景选择两种写法,修正后的完整代码如下:
import csv import boto3 import urllib3 import tempfile import os import io import openpyxl s3 = boto3.client('s3') bucket = os.environ['S3_BUCKET'] http = urllib3.PoolManager() # 此处补充你未提供的readS3实现,若已有可删除 def readS3(key): resp = s3.get_object(Bucket=bucket, Key=key) return resp['Body'].read() def lambda_handler(event, context): file = readS3('example.xlsx') latest_scan = openpyxl.load_workbook(io.BytesIO(file), data_only=True) sh = latest_scan.active csv_lines = [] for row in sh['A']: if not row.value: continue # 跳过空行避免接口请求错误 r5 = http.request( 'GET', f'https://example.com/api/{row.value}', headers={ 'Accept': 'text/csv' } ) csv_lines.append(r5.data.decode('utf-8')) full_csv = ''.join(csv_lines) # 方案1:保留临时文件逻辑的正确写法 with tempfile.TemporaryFile(mode='w+', encoding='utf-8', suffix='.csv') as temp: temp.write(full_csv) temp.seek(0) s3.put_object(Body=temp.read(), Bucket=bucket, Key='test.csv') # 方案2:数据量小的场景下更简化的写法,无需临时文件,直接上传字节 # s3.put_object(Body=full_csv.encode('utf-8'), Bucket=bucket, Key='test.csv')
主要改动点:
- 补全了缺失的依赖模块导入,补充了
readS3的基础实现 - 移除了错误的嵌套
open()调用,直接操作TemporaryFile返回的文件对象 - 修正了
s3.put_object的传参格式,显式指定Body参数接收上传内容 - 增加空行判断逻辑,避免空单元格导致接口请求路径异常
- 移除冗余的逐字符写入逻辑,直接写入完整CSV字符串提升效率
内容的提问来源于stack exchange,提问作者Kostas
相关产品推荐
相关产品推荐

