109:大型CSV文件的处理方式

生成大的CSV文件:

  108是生成的一个小的csv文件,如果想要生成大型的csv文件,那么以上方式将有可能会发生超时的情况(服务器要生成一个大型csv文件,需要的时间可能会超过浏览器默认的超时时间)。这时候我们可以借助另外一个类,叫做StreamingHttpResponse对象,这个对象是将响应的数据作为一个流返回给客户端,而不是作为一个整体返回。示例代码如下:from django.http import HttpResponse, JsonResponse, StreamingHttpResponse

 loader, context
import json, csv

# Create your views here.

def large_csv(request):
    resp = StreamingHttpResponse(content_type='text/csv')
    resp['Content-Disposition'] = "attachment;filename='large.csv'"
    rows = ("Row {}, {}
".format(row, row) for row in range(1,100000))
    resp.streaming_content = rows

    # 对比上下两种方法
# resp = HttpResponse(content_type='text/csv') # resp['Content-Disposition'] = "attachment;filename='largs.csv'" # mywrite = csv.writer(resp) # for i in range(1,1000000): # mywrite.writerow([i, i*2]) return resp

  这里我们构建了一个非常大的数据集rows,并且将其变成一个迭代器。然后因为StreamingHttpResponse的第一个参数只能是一个生成器,因此我们使用圆括号(writer.writerow(row) for row in rows),并且因为我们要写的文件是csv格式的文件,因此需要调用writer.writerowrow变成一个csv格式的字符串。而调用writer.writerow又需要一个中间的容器,因此这里我们定义了一个非常简单的类Echo,这个类只实现一个write方法,以后在执行csv.writer(pseudo_buffer)的时候,就会调用Echo.writer方法。

注意:StreamingHttpResponse会启动一个进程来和客户端保持长连接,所以会很消耗资源。所以如果不是特殊要求,尽量少用这种方法。

关于StreamingHttpResponse:

这个类是专门用来处理流数据的。使得在处理一些大型文件的时候,不会因为服务器处理时间过长而到时连接超时。这个类不是继承自HttpResponse,并且跟HttpResponse对比有以下几点区别:

  • 这个类没有属性content,相反是streaming_content
  • 这个类的streaming_content必须是一个可以迭代的对象。
  • 这个类没有write方法,如果给这个类的对象写入数据将会报错。

注意:StreamingHttpResponse会启动一个进程来和客户端保持长连接,所以会很消耗资源。所以如果不是特殊要求,尽量少用这种方法。

# 对比上下两种方法
# resp = HttpResponse(content_type='text/csv')
# resp['Content-Disposition'] = "attachment;filename='largs.csv'"
# mywrite = csv.writer(resp)
# for i in range(1,1000000):
# mywrite.writerow([i, i*2])