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

Django 2.0 + DRF处理POST请求中超大JSON的高效方案咨询

处理Django DRF中超大JSON文件的高效方案

我之前接手过类似的超大JSON导入任务,数GB的文件、数百万条数据,一开始也是内存爆得一塌糊涂,后来踩了不少坑,总结出几个关键思路,应该能解决你的问题:

1. 绝对不要一次性加载整个JSON文件

这是内存爆炸的根源!别用json.load()把整个文件塞进内存,改用流式解析,只在内存中保留当前处理的单条数据。

推荐用ijson库(专门处理大JSON的流式解析工具),它可以逐对象读取JSON,不会加载整个文件。安装很简单:

pip install ijson

比如你的JSON是数组格式([{}, {}, ...]),可以这样解析:

import ijson

with open('huge_data.json', 'rb') as f:
    # 'item'对应数组中的每个元素,根据你的JSON结构调整路径
    for item in ijson.items(f, 'item'):
        # 处理单条item,比如转成模型实例
        process_single_item(item)

如果你的JSON是每行一个对象(JSON Lines格式),更简单,直接逐行读取:

import json

with open('huge_data.json', 'r') as f:
    for line in f:
        item = json.loads(line.strip())
        process_single_item(item)

2. 批量操作+手动清理内存

Django的save()方法每次都会触发数据库交互,不仅慢还会累积内存。改用bulk_create()批量插入,同时处理完一批后手动清理内存:

from django.db import transaction
import gc
from myapp.models import YourModel

batch_size = 1000  # 可根据服务器内存调整,建议1000-10000之间
batch = []

with open('huge_data.json', 'rb') as f:
    for item in ijson.items(f, 'item'):
        obj = YourModel(
            field1=item['key1'],
            field2=item['key2'],
            # 映射你的模型字段
        )
        batch.append(obj)

        if len(batch) >= batch_size:
            # 用事务包裹,保证批量插入的原子性
            with transaction.atomic():
                YourModel.objects.bulk_create(batch)
            # 强制清理内存:清空列表、删除引用、触发垃圾回收
            batch.clear()
            del batch[:]
            gc.collect()

# 处理最后一批剩余数据
if batch:
    with transaction.atomic():
        YourModel.objects.bulk_create(batch)

这里的关键是:处理完一批就立刻清空batch,并调用gc.collect()强制回收内存——Django的ORM对象有时候不会自动释放,手动触发很有必要。

3. 用异步任务脱耦web进程

如果是通过DRF接口上传超大文件,绝对不要在web请求中同步处理!web进程内存有限,而且请求超时时间也不允许。应该把文件保存到临时目录,然后丢给异步任务处理(比如用Celery):

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.parsers import FileUploadParser
from celery import shared_task
import os

@shared_task
def process_large_json_task(file_path):
    # 这里放上面的流式解析+批量插入代码
    batch_size = 1000
    batch = []
    with open(file_path, 'rb') as f:
        for item in ijson.items(f, 'item'):
            obj = YourModel(...)
            batch.append(obj)
            if len(batch) >= batch_size:
                with transaction.atomic():
                    YourModel.objects.bulk_create(batch)
                batch.clear()
                gc.collect()
    if batch:
        with transaction.atomic():
            YourModel.objects.bulk_create(batch)
    # 处理完删除临时文件
    os.remove(file_path)

class LargeJSONUploadView(APIView):
    parser_classes = (FileUploadParser,)

    def post(self, request, filename, format=None):
        file_obj = request.data['file']
        # 保存到临时目录
        temp_path = f'/tmp/large_upload_{filename}'
        with open(temp_path, 'wb+') as dest:
            for chunk in file_obj.chunks():
                dest.write(chunk)
        # 启动异步任务
        process_large_json_task.delay(temp_path)
        return Response({'status': 'processing'}, status=202)

这样web进程只负责接收文件,真正的处理在后台异步进行,不会占用web服务的内存,也不会超时。

4. 极端情况:绕过ORM用原生SQL

如果数据量实在大到ORM都扛不住(比如数亿条),可以直接用Django的游标执行原生SQL批量插入,跳过ORM对象的内存开销:

from django.db import connection

with open('huge_data.json', 'rb') as f:
    batch = []
    for item in ijson.items(f, 'item'):
        # 把数据转成SQL需要的元组
        data_tuple = (item['key1'], item['key2'], ...)
        batch.append(data_tuple)
        if len(batch) >= 10000:
            with connection.cursor() as cursor:
                # 构造批量插入SQL
                placeholders = ', '.join(['%s'] * len(data_tuple))
                sql = f"INSERT INTO your_table (field1, field2, ...) VALUES {placeholders}"
                cursor.executemany(sql, batch)
            batch.clear()
            gc.collect()

这种方式内存占用极低,但要注意SQL注入风险(确保数据是可信的),以及字段类型要和数据库匹配。

几个避坑小贴士

  • 不要在循环中保留任何不必要的对象引用,比如不要把所有模型实例存在一个大列表里;
  • 调整batch_size:太大容易内存溢出,太小会增加数据库IO,建议根据服务器内存测试;
  • 如果用Docker部署,记得给容器分配足够的内存,但更重要的是优化代码而非加内存;
  • 监控内存使用:可以用psutil库在代码中打印内存占用,找到内存泄漏的点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:42:22