Сервер должен стримить большую CSV-выгрузку (100k строк) клиенту через
HTTP. Какая реализация правильная, какая нет?
senior
correct_vs_wrong
#700
Вариант 1
# FastAPI — StreamingResponse + async generator + chunked
from fastapi import FastAPI
from fastapi.responses import StreamingResponse
app = FastAPI()
async def csv_iter(query):
yield "id,name,total\n"
# курсор по БД, batch 1000, async
async for batch in db.stream(query, batch_size=1000):
buf = []
for row in batch:
buf.append(f"{row.id},{row.name},{row.total}\n")
yield "".join(buf)
@app.get("/export")
async def export(filter: str):
q = build_query(filter)
return StreamingResponse(
csv_iter(q),
media_type="text/csv",
headers={
"Content-Disposition": 'attachment; filename="export.csv"',
"X-Accel-Buffering": "no", # nginx: не буферизовать
},
)
Вариант 2
# Загружаем всё в память и возвращаем
@app.get("/export")
def export(filter: str):
rows = db.execute(query).fetchall() # 100k tuples в памяти
csv = "id,name,total\n"
for r in rows: # Python string + new string каждый раз
csv += f"{r.id},{r.name},{r.total}\n"
return Response(csv, media_type="text/csv")
Чтобы решить вопрос и сохранить попытку — войди.