Django实现下载100G的超大CSV文件

关注我的公众号「DevOps724」,获取最新的内容分享,带你探索DevOps的无限可能!分享最新的行业趋势、深入的技术分析和实用的工具,帮助你掌握自动化、云计算、持续集成和部署等核心概念。

在处理大数据集的时候,我们经常遇到的一个问题是内存使用。当我们试图生成一个大型文件,如 CSV,并尝试将其全部加载到内存中时,可能会遇到内存不足的问题。幸运的是,Django 提供了一个解决方案:流传输。本文将详细的讲述如何利用 Django 进行大型 CSV 文件的流传输。

流传输的基础概念

流传输是一种技术,允许你一次发送一小部分响应,而不是一次性加载整个响应到内存中。这种技术对于服务大文件,如图像,音频和大型数据集非常有用。

创建 Django StreamingHttpResponse 对象

StreamingHttpResponse 对象允许我们将响应内容按部分,或者说"流"的形式发送给客户端。试看以下代码:

python 复制代码
from django.http import StreamingHttpResponse

def big_file_download(request):
    def file_iterator(file_name, chunk_size=512):
        with open(file_name, "rb") as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break
    response = StreamingHttpResponse(file_iterator('big_file.csv'))
    return response

在这里,我们首先创建一个生成器函数 file_iterator,它以 chunk_size 为单位读取文件,然后用这个生成器函数作为 StreamingHttpResponse 的参数,从而创建出一个可以流传输的响应对象。

实现 Django 流传输大型 CSV 文件

现在,我们知道了如何创建 StreamingHttpResponse 对象,接着看一下如何用它来流传输大型 CSV 文件:

python 复制代码
import csv
from django.http import StreamingHttpResponse
from .models import Person

class Echo:
    def write(self, value):
        return value

def streaming_csv_view(request):
    persons = Person.objects.all().values_list('name', 'age', 'city')
    pseudo_buffer = Echo()
    writer = csv.writer(pseudo_buffer)
    
    response = StreamingHttpResponse((writer.writerow(person) for person in persons),
                                     content_type="text/csv")
    response['Content-Disposition'] = 'attachment; filename="persons.csv"'
    return response

在上述代码中,我们创建了一个 Echo 类,并将其实例 pseudo_buffer 作为 csv.writer 的参数。这样,我们可以以迭代的方式写入 CSV 行,而不必把它们全部加载到内存中。之后,我们把这个 writerow 方法的迭代器作为 StreamingHttpResponse 的参数。注意,我们此时仍需要设置正确的 MIME 类型和 Content-Disposition 头部。

总结

这就是如何使用 Django 的 StreamingHttpResponse 对象来流传输大型 CSV 文件。完成这个特性后,你应该能够更高效地处理大数据集,且大大降低了内存使用。希望这篇文章对你的开发工作有所帮助。

相关推荐
桦说编程2 小时前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
舒一笑2 小时前
大模型时代的程序员成长悖论:如何在AI辅助下不失去竞争力
后端·程序员·掘金技术征文
lang201509282 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
码界奇点3 小时前
Django视图从基础到高级的全面解析
数据库·django·sqlite·web·python3.11
小羊在睡觉3 小时前
golang定时器
开发语言·后端·golang
用户21411832636023 小时前
手把手教你在魔搭跑通 DeepSeek-OCR!光学压缩 + MoE 解码,97% 精度还省 10-20 倍 token
后端
追逐时光者3 小时前
一个基于 .NET 开源、功能强大的分布式微服务开发框架
后端·.net
刘一说4 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多4 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring
清静诗意4 小时前
Django from_queryset 源码深度解析:动态生成 Manager 的奥秘
django·queryset