从 StringIO 写入时添加到文件中的新行

问题描述 投票:0回答:1

我有一段代码,可以将 csv 响应写入

StringIO()
对象。我通过端点返回此对象,并使用此输出生成将存储在服务器上的 csv 文件。

@app.post('/csv-data')
def get_csv(data: DataRequest):
    if not data.headers:
        raise HTTPException(status_code=400, detail="Headers cannot be empty")
    if data.number_of_records <= 0:
        raise HTTPException(status_code=400, detail="Number of requested records must be more than 0")

    timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
    file_name = f"data_{timestamp}.csv"
    file_path = os.path.join(STORAGE_DIR, file_name)

    headers = [
        {"name": header.name, "description": header.description, "sample_data": header.sample_data}
        for header in data.headers
    ]
    response = open_ai_interface.generate_data(headers, data.number_of_records)

    output = StringIO()
    csvwriter = csv.writer(output, quoting=csv.QUOTE_MINIMAL)
    for row in response:
        csvwriter.writerow(row.split(','))


    output.seek(0)
    with open(file_path, 'w') as f:
        f.write(output.getvalue())
    
    output.seek(0)
    return StreamingResponse(output, media_type="text/csv", headers={"Content-Disposition": f"attachment; filename={file_name}"})

我面临的问题是生成的 .csv 文件在每条记录之间包含一条额外的行。当我通过浏览器或邮递员发送请求时,我得到的响应是记录之间的新行。 这让我假设可能有更好的方法将 csv 数据写入文件。我很感激建议

python file fastapi
1个回答
0
投票

传递给

TextIOWrapper
的类似
csv.writer
的对象被记录为需要包含
newline=''
作为参数以防止 的翻译。 不幸的是,虽然
io.StringIO
newline
参数,但它并不像
TextIOWrapper
那样支持它:

字符串IO

newline 参数的工作方式与

TextIOWrapper
类似,只不过在将输出写入流时,如果 newline
None
,则在所有平台上换行符都将写为
\n

如果没有

newline=None
csv.writer
会直接将其默认的“excel”方言(换行符为
\r\n
)写入流。 稍后,当将流写入文件时,在 Windows 系统上以 text 模式 (
mode='r'
) 打开文件会将
\n
转换为
\r\n
,从而导致
\r\n
变为
\r\r\n
。 这是额外的换行符。

TL;DR:要修复,请使用

output = StringIO(newline=None)

© www.soinside.com 2019 - 2024. All rights reserved.