我正在使用Django的StreamingHttpResponse动态地流式传输一个大的CSV文件,根据文档,一个迭代器被传递给响应的streaming_content
参数:
import csv
from django.http import StreamingHttpResponse
def get_headers():
return ['field1', 'field2', 'field3']
def get_data(item):
return {
'field1': item.field1,
'field2': item.field2,
'field3': item.field3,
}
# StreamingHttpResponse requires a File-like class that has a 'write' method
class Echo(object):
def write(self, value):
return value
def get_response(queryset):
writer = csv.DictWriter(Echo(), fieldnames=get_headers())
writer.writeheader() # this line does not work
response = StreamingHttpResponse(
# the iterator
streaming_content=(writer.writerow(get_data(item)) for item in queryset),
content_type='text/csv',
)
response['Content-Disposition'] = 'attachment;filename=items.csv'
return response
我的问题是:如何在CSV编写器上手动写入行?手动调用writer. writerow(data)或writer. writeader()(也在内部调用writerow())似乎不会写入数据集,而是仅将streaming_content生成/流传输的数据写入输出数据集。
3条答案
按热度按时间yh2wf1be1#
答案是使用生成器函数生成结果,而不是动态计算结果(在StreamingHttpResponse的
streaming_content
参数内),并使用我们创建的伪缓冲区(Echo类)向响应写入一行:cedebl8k2#
建议的解决方案实际上可能会导致不正确/不匹配的CSV(标题与数据不匹配)。您可能希望将受影响的部分替换为以下内容:
这是来自
writeheader
www.example.com的实现https://github.com/python/cpython/blob/08045391a7aa87d4fbd3e8ef4c852c2fa4e81a8a/Lib/csv.py#L141:L143由于某种原因,它在
yield
中表现不佳希望这对以后的人有帮助:)
还请注意,如果使用python 3.8+,则无需修复,因为此PR:https://bugs.python.org/issue27497
58wvjzkj3#
你可以在python中使用itertools链接生成器,将标题行添加到查询集行
下面是您操作方法:
你会得到一个带有标题和查询集的csv文件: