如何在Python中使用csv.writer写入命名临时CSV文件?
问题原因
你遇到的字符拆分问题,核心是给csv.writer.writerow()传入了字符串。writerow()要求传入可迭代的列数据(比如列表、元组),而字符串本身是字符的迭代器,所以它会把每个字符当成单独的CSV列,导致输出异常。
另外你之前的代码还有低级错误:writer = csv.write(fileName)不仅拼错了方法名(应为csv.writer),还在临时文件创建前就初始化了writer,逻辑完全不合理。
解决方案
根据你的场景,推荐两种规范的实现方式,优先选第一种(直接处理原始字典数据):
方案1:直接处理原始字典数据(推荐)
你的原始数据是字典列表,用csv.DictWriter可以直接映射表头和字段,避免手动拼接字符串的风险(比如字段含逗号、引号时会自动处理),代码更健壮:
import csv import tempfile import boto3 # 原始数据 allData = [ {'name': 'Adam', 'code': '12', 'points': 9.7, 'age': '34'}, {'name': 'Sam', 'code': '13', 'points': 8.4, 'age': '34'}, # 剩余998条数据... ] # 创建临时CSV文件(w+t模式支持读写) with tempfile.NamedTemporaryFile(mode="w+t", suffix=".csv", delete=True) as temp_file: # 初始化DictWriter,指定表头,忽略字典中多余的字段 writer = csv.DictWriter( temp_file, fieldnames=['Name', 'Code'], extrasaction='ignore' ) writer.writeheader() # 写入表头 # 遍历写入数据 for item in allData: # 映射字段名(如果原始key和表头大小写不一致,这里统一转换) writer.writerow({ 'Name': item['name'], 'Code': item['code'] }) # 重置文件指针到开头,确保上传时读取完整内容 temp_file.seek(0) # 用Boto3上传到S3 s3_client = boto3.client('s3') s3_client.upload_file( Filename=temp_file.name, Bucket='your-bucket-name', Key='target-path/your-file.csv' )
方案2:处理已过滤的字符串列表
如果你非要用已经拼接好的字符串(比如"Adam,12"),要么直接写入文件(就像你最开始的代码那样),要么把字符串拆分成列表再传给writerow():
import csv import tempfile import boto3 # 已过滤的字符串列表 allData_filtered = ["Adam,12", "Sam,13", ...] with tempfile.NamedTemporaryFile(mode="w+t", suffix=".csv", delete=True) as temp_file: writer = csv.writer(temp_file) writer.writerow(['Name', 'Code']) # 写入表头 for line in allData_filtered: # 按逗号分割成列表(注意:如果字段本身含逗号,这种方法会出错) writer.writerow(line.split(',')) temp_file.seek(0) # 上传S3 s3_client = boto3.client('s3') s3_client.upload_file(temp_file.name, 'your-bucket-name', 'target-file.csv')
关于StringIO的用法
如果想先在内存中生成CSV内容,再写入临时文件或直接上传,可以用StringIO:
import csv from io import StringIO import boto3 allData = [{'name': 'Adam', 'code': '12'}, ...] # 内存中生成CSV csv_buffer = StringIO() writer = csv.DictWriter(csv_buffer, fieldnames=['Name', 'Code']) writer.writeheader() for item in allData: writer.writerow({'Name': item['name'], 'Code': item['code']}) csv_buffer.seek(0) # 直接用upload_fileobj上传内存内容到S3(不需要临时文件) s3_client = boto3.client('s3') s3_client.upload_fileobj( Fileobj=csv_buffer, Bucket='your-bucket-name', Key='target-file.csv' )
内容的提问来源于stack exchange,提问作者layman
相关产品推荐
相关产品推荐

