You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django+IIS+Postgres环境下万级数据CSV导出条数与筛选结果不一致问题

问题根因排查

1. 代码逻辑错误(首要问题)

你当前的实现完全没有用到StreamingHttpResponse的流式特性:

  • 代码中filter_list = list(filter.values_list())会一次性把所有符合条件的记录全部加载到内存中,当数据量达到数万级别时,要么触发内存超限被进程杀掉,要么触发IIS的超时/响应大小限制,导致返回的数据被截断,最终表现为导出行数少于实际行数。
  • 本地环境运行正常是因为本地没有IIS的各类限制,且测试时的网络环境更稳定。

2. IIS配置问题

IIS默认有多个限制会导致大响应被截断:

  • 响应超时限制:默认IIS的FastCGI超时时间一般是90秒,大查询+全量加载数据的耗时很容易超过这个阈值,导致IIS直接中断连接。
  • 响应大小限制:默认IIS的最大响应大小是30MB左右,数万条CSV记录很容易超过这个值,导致返回内容被截断。

修复方案

第一步:改写代码实现真正的流式导出

不要提前把QuerySet转为list,使用Django QuerySet的iterator()方法逐条加载数据,避免一次性占用大量内存:

import csv
from django.http import StreamingHttpResponse
from urllib.parse import urlsplit, parse_qs

class Echo(object):
    """An object that implements just the write method of the file-like
    interface.
    """
    def write(self, value):
        """Write the value by returning it, instead of storing in a buffer."""
        return value

def export_to_csv(request):
    # 先处理筛选逻辑
    all_objects = DeviceVulns.objects.all()
    url = request.GET.get('filter_url')
    query = urlsplit(url).query
    params = dict(parse_qs(query))
    params_dict = {k: v[0] for k, v in params.items()}
    filter_qs = DeviceVulnsFilter(params_dict, queryset=all_objects).qs.values_list(
        'id', 'hostname', 'ip_address', 'os_name', 'vuln_title', 'cvss_score', 
        'vuln_found_date', 'is_exploitable', 'exploit_skill_level'
    )
    # 定义生成器,先输出表头,再逐条输出数据
    def row_generator():
        # 输出表头
        yield ['ID','Hostname', 'IP Address', 'OS_Name', 'Vuln Title','CVSS Score','Vuln Earliest Found Date On Asset','Vuln Exploitable?','Vuln Exploit Skill Level']
        # 使用iterator逐条加载数据,避免全量加载到内存
        for item in filter_qs.iterator(chunk_size=1000):
            yield [item[1], item[2], item[3], item[4], item[5], item[6], item[7], item[8]]
    
    pseudo_buffer = Echo()
    writer = csv.writer(pseudo_buffer)
    response = StreamingHttpResponse(
        (writer.writerow(row) for row in row_generator()),
        content_type="text/csv"
    )
    response['Content-Disposition'] = 'attachment; filename="filtered-data.csv"'
    return response

第二步:调整IIS配置

  • 调整FastCGI超时时间:打开IIS管理器 → 找到对应站点的FastCGI设置 → 将activityTimeout和requestTimeout调整为600秒(可根据实际导出最大耗时调整)
  • 调整响应大小限制:打开IIS管理器 → 站点的「请求筛选」→ 「编辑功能设置」→ 将「允许的最大内容长度」调整为104857600(即100MB,可按需扩大)
  • 关闭响应缓冲:IIS中对应站点的「输出缓存」→ 关闭动态内容缓存,避免IIS缓冲整个流式响应才返回。

第三步:数据库可选优化

800万条记录的表可以给常用的筛选字段加索引,降低筛选查询的耗时,进一步减少超时概率。


内容的提问来源于stack exchange,提问作者Gary Dorman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 20:36:05