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

Django中CSV导入速度极慢,求更快实现方案

优化CSV导入SQLite数据库的速度方案

你的代码慢的核心原因是每次update_or_create都会触发两次数据库操作(先查询是否存在,再执行插入/更新),2100行数据就会产生至少4200次数据库交互,加上Django ORM的额外开销,导致耗时过长。以下是几个高效的优化方法:

方法1:批量查询+分组批量操作

先一次性读取所有CSV数据,批量查询已存在的sn,再将数据分为「新增」和「更新」两组,分别用批量API处理,大幅减少数据库交互次数:

from django.db import transaction

def import_csv(reader):
    # 收集所有CSV数据和对应的sn
    rows = list(reader)
    sn_list = [row[0] for row in rows]
    
    # 批量查询已存在的sn及其对象,用字典映射方便快速查找
    existing_items = {item.sn: item for item in Item.objects.filter(sn__in=sn_list)}
    
    create_list = []
    update_list = []
    
    for row in rows:
        sn = row[0]
        if sn in existing_items:
            # 更新已有对象的字段
            item = existing_items[sn]
            item.field_a = row[1]
            item.field_b = row[2]
            item.field_c = row[3]
            item.field_d = row[4]
            update_list.append(item)
        else:
            # 构建新对象加入新增列表
            create_list.append(Item(
                sn=sn,
                field_a=row[1],
                field_b=row[2],
                field_c=row[3],
                field_d=row[4]
            ))
    
    # 原子事务中执行批量操作,保证数据一致性
    with transaction.atomic():
        if create_list:
            Item.objects.bulk_create(create_list)
        if update_list:
            Item.objects.bulk_update(update_list, ['field_a', 'field_b', 'field_c', 'field_d'])

方法2:使用SQLite原生INSERT OR REPLACE批量执行

直接调用数据库原生语句批量处理,绕开Django ORM的单条操作开销,速度提升最明显:

from django.db import connection

def import_csv(reader):
    # 跳过CSV表头(如果有)
    next(reader)
    
    # 整理批量插入数据
    data_batch = []
    for row in reader:
        data_batch.append((row[0], row[1], row[2], row[3], row[4]))
    
    # 执行原生SQL批量操作
    with connection.cursor() as cursor:
        cursor.executemany("""
            INSERT OR REPLACE INTO yourapp_item (sn, field_a, field_b, field_c, field_d)
            VALUES (?, ?, ?, ?, ?)
        """, data_batch)

注意:替换yourapp_item为你的实际数据库表名(Django默认规则是「应用名_模型名」小写);INSERT OR REPLACE会删除旧记录再插入新记录,若模型有其他需保留的关联字段,谨慎使用。

方法3:最小改动优化——手动控制事务

Django默认每次ORM操作都会自动提交事务,用transaction.atomic()包裹所有操作,减少事务提交的开销,是对原有代码的最小改动:

from django.db import transaction

def import_csv(reader):
    with transaction.atomic():
        for row in reader:
            Item.objects.update_or_create(
                sn=row[0],
                defaults={
                    "field_a": row[1],
                    "field_b": row[2],
                    "field_c": row[3],
                    "field_d": row[4],
                }
            )

该方法能小幅提升速度,但效果不如前两种方法显著。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:39:47