StreamingHttpResponse比HttpResponse更适合导出,因为后者将百万行CSV拼成大字符串致内存溢出,前者通过生成器逐行yield bytes并立即flush,内存仅保留当前chunk;需注意禁用Nginx proxy_buffering、数据库用.iterator()、手动处理BOM与RFC 4180转义。

StreamingHttpResponse 为什么比 HttpResponse 更适合导出
因为 HttpResponse 会把整个 CSV 或 Excel 内容拼成一个大字符串再发出去,百万行数据轻松吃光 2GB 内存;而 StreamingHttpResponse 接收生成器,每 yield 一行就立刻 flush 到客户端,内存里只留当前 chunk。
但代价是:不能中途改 Content-Length,不能用 render(),也不能在生成过程中动态加 header(除了 Content-Type 和 Content-Disposition)。
写 CSV 流式生成器时最容易踩的坑
常见错误包括:用 csv.writer 写到 StringIO —— 又回到内存堆积;字段含换行或双引号没转义;忘了加 UTF-8 BOM 导致 Excel 打开乱码;数据库查询没用 .iterator(chunk_size=2000),QuerySet 还是全量缓存。
-
yield必须返回bytes,不是str;开头加b'\xef\xbb\xbf' - 字段含
"要变成"",整字段用双引号包裹 - 行尾用
\r\n,别用\n - 数据库查完立刻
.iterator(chunk_size=2000),否则没用
部署后流式响应失效?多半是 Nginx 搞的鬼
本地跑得好好的,一上生产就卡住、延迟高、最后超时——大概率是 Nginx 默认开启 proxy_buffering,把流式响应攒满再发。
立即学习“Python免费学习笔记(深入)”;
图片提示词生成器?不止如此。 马甲系统 —— 把脑海中的画面,翻译成AI能理解的专业表达。 用得越多,它越懂你:首次需要多问几句确认方向,用久了几乎一说就懂。 用得越多,它越快:缓存机制让后续对话越来越省。 RAG进化:成功案例持续入库,越跑越聪明。 输入「新手指南」查看完整功能介绍
必须在 location 块里加:
proxy_buffering off; proxy_buffer_size 128k;
如果用 Gunicorn,还要确认 --timeout 足够长(比如 120),否则 worker 直接 kill 连接。
Excel 导出比 CSV 更容易爆内存
CSV 是纯文本,可控;Excel(.xlsx)本质是 ZIP 包,openpyxl 或 xlsxwriter 构建时会缓存整张表结构和样式,10 万行就可能占几百 MB。
真要导 Excel:
- 优先考虑前端用 SheetJS 生成,后端只提供 JSON 数据
- 若必须后端生成,用
openpyxl的write_only=True模式 +append() - 超 5 万行直接切回 CSV,或者转成 Parquet 供下游下载解析
最常被忽略的一点:BOM 和换行符控制只对 CSV 有效;Excel 文件本身不认 BOM,加了反而可能损坏文件头。

















