AWS Lambda+S3 TXT转CSV代码报错:NoneType无open属性求助
解决S3 TXT转CSV上传时的'NoneType'属性错误
问题背景
一段用于将S3桶testsigma2中的TXT文件转换为CSV格式后上传至testsigma3桶的Lambda代码,运行时抛出以下错误:
{ "errorMessage": "'NoneType' object has no attribute 'open'", "errorType": "AttributeError", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 25, in lambda_handler\n z.open(filename),\n" ] }
错误原因
to_csv返回值误解:当pandas.DataFrame.to_csv()传入已打开的BytesIO对象时,会直接将内容写入该对象,返回值为None,所以变量z是None,调用z.open()必然报错。- 未重置文件指针:
BytesIO写入内容后,指针停在末尾,直接上传会导致读取空内容。 - 变量未定义:
filename变量未声明,代码中直接使用会引发额外错误。 - 参数拼写错误:Lambda处理函数的第一个参数拼写错误(
evenBytesIOt应为event)。 - 提示文本错误:else分支提示“不是zip文件”,但实际判断的是TXT文件,逻辑不符。
修正后的代码
import pandas as pd import boto3 from io import BytesIO def lambda_handler(event, context): s3_resource = boto3.resource('s3') source_bucket = 'testsigma2' target_bucket = 'testsigma3' my_bucket = s3_resource.Bucket(source_bucket) for file in my_bucket.objects.all(): file_key = file.key if file_key.endswith('.txt'): # 获取源文件内容 s3_obj = s3_resource.Object(bucket_name=source_bucket, key=file_key) buffer = BytesIO(s3_obj.get()['Body'].read()) # 读取TXT为DataFrame(若TXT非CSV分隔格式,需手动指定sep参数) dataframe1 = pd.read_csv(buffer) # 重置buffer指针到开头,准备写入CSV内容 buffer.seek(0) # 将DataFrame写入buffer,覆盖原有内容 dataframe1.to_csv(buffer, index=None) # 再次重置指针到开头,准备上传 buffer.seek(0) # 生成目标文件名:替换后缀为.csv target_key = file_key.rsplit('.', 1)[0] + '.csv' # 上传到目标桶 s3_resource.meta.client.upload_fileobj( buffer, Bucket=target_bucket, Key=target_key ) else: print(f"{file_key} is not a TXT file.")
关键改动说明
- 修正Lambda函数参数拼写错误,符合AWS Lambda规范。
- 复用同一个
BytesIO对象,写入CSV后两次调用seek(0):第一次是覆盖写入前重置指针,第二次是上传前重置到文件开头。 - 移除无效的
z变量,直接将buffer传入upload_fileobj。 - 生成合理的目标文件名,将原TXT后缀替换为.csv。
- 修正else分支的提示文本,匹配实际判断逻辑。
内容的提问来源于stack exchange,提问作者Pedro Cardenas
相关产品推荐
相关产品推荐

