Skip to main content
 首页 » 编程设计

python之使用 xlrd 读取 django 批量 excel 文件太慢

2024年10月25日37birdshome

我在 Django 模型中加载 excel 文件并使用 xlrd 读取它并存储在数据库中。 加载大约 20k 行需要 1 分钟..但是我的文件有 160k 行它花了大约 8 分钟,所以我需要将读取和存储这种批量文件的时间减少到不到一分钟。我应该怎么做才能减少加载时间。所有可能的方法是什么??

def upload_file(request): 
    if request.method == 'POST': 
        form = UploadFileForm(request.POST, request.FILES) 
        if form.is_valid(): 
            newdoc = Upload(file = request.FILES['file']) 
            newdoc.save() 
            xlbook = open_workbook(newdoc.file.name) 
            sheet = xlbook.sheet_by_index(0) 
            field = [sheet.cell_value(0,c) for c in range(sheet.ncols)] 
            temp = [sheet.cell_value(c,0) for c in range(sheet.nrows)] 
            value = [[sheet.cell_value(r,c) for c in range(sheet.ncols)]for r in range (sheet.nrows)] 
            data = {} 
            if request.POST.get('check'):        
                Sales.objects.filter(OrderID__in = temp[1:]).delete() 
            for n in range(0,sheet.nrows): 
                if n > 0: 
                    list = value[n] 
                    for i in range(0,len(field)): 
                        data[field[i]] = list[i] 
                if data: 
                    date_value = xldate_as_tuple(sheet.cell_value(n,1),xlbook.datemode) 
                    data["Date"] = datetime(*date_value[:3]) 
                    add = Sales.objects.get_or_create(**data) 
            return HttpResponseRedirect('/salesdata/') 
    if request.method == 'GET': 
       form = UploadFileForm(request.POST, request.FILES)  
    return render(request,'salesdata/upload.html', {'form': form}) 

请您参考如下方法:

第一,不要在 View 中这样做。用 Celery 左右启动后台任务,然后返回。不要让用户等待。

其次,问题是您要为每一行执行 get_or_create;那很慢。您可以先列出未保存的 Sales 实例,然后使用 Sales.objects.bulk_create 创建它们。这样它就是一个插入查询,速度会快很多。

不幸的是,它只会插入,不会更新已经存在的数据。解决这个问题比我现在想放在这个答案中的要多,最好的方法取决于与通常情况下的插入相比有多少行将被更新。最坏的情况是,您确实必须为每一行执行一个 sql UPDATE,这总是很慢。