GVKun编程网logo

在Django中流式传输CSV文件(django视频流传输)

14

在本文中,我们将给您介绍关于在Django中流式传输CSV文件的详细内容,并且为您解答django视频流传输的相关问题,此外,我们还将为您提供关于c#–如何在asp.net中流式传输视频内容?、Dja

在本文中,我们将给您介绍关于在Django中流式传输CSV文件的详细内容,并且为您解答django视频流传输的相关问题,此外,我们还将为您提供关于c# – 如何在asp.net中流式传输视频内容?、Django 流式响应中文csv样例、django 生成和下载CSV文件、Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?的知识。

本文目录一览:

在Django中流式传输CSV文件(django视频流传输)

在Django中流式传输CSV文件(django视频流传输)

我正在尝试将csv文件作为附件下载流式传输。CSV文件的大小已达到4MB或更大,我需要一种让用户主动下载文件的方法,而不必等待所有数据都先创建并提交到内存中。

我首先使用了我自己的基于DjangoFileWrapper类的文件包装器。那失败了。然后,我在这里看到了一种使用生成器流式传输响应的方法:
如何使用Django流式传输HttpResponse

当我在生成器中引发错误时,可以看到我正在使用该get_row_data()函数创建正确的数据,但是当我尝试返回响应时,它返回为空。我也禁用了Django
GZipMiddleware。有人知道我在做什么错吗?

编辑:我遇到的问题与ConditionalGetMiddleware。我必须替换它,代码在下面的答案中。

这是视图:

from django.views.decorators.http import condition@condition(etag_func=None)def csv_view(request, app_label, model_name):    """ Based on the filters in the query, return a csv file for the given model """    #Get the model    model = models.get_model(app_label, model_name)    #if there are filters in the query    if request.method == ''GET'':        #if the query is not empty        if request.META[''QUERY_STRING''] != None:            keyword_arg_dict = {}            for key, value in request.GET.items():                #get the query filters                keyword_arg_dict[str(key)] = str(value)            #generate a list of row objects, based on the filters            objects_list = model.objects.filter(**keyword_arg_dict)        else:            #get all the model''s objects            objects_list = model.objects.all()    else:        #get all the model''s objects        objects_list = model.objects.all()    #create the reponse object with a csv mimetype    response = HttpResponse(        stream_response_generator(model, objects_list),        mimetype=''text/plain'',        )    response[''Content-Disposition''] = "attachment; filename=foo.csv"    return response

这是我用来流式传输响应的生成器:

def stream_response_generator(model, objects_list):    """Streaming function to return data iteratively """    for row_item in objects_list:        yield get_row_data(model, row_item)        time.sleep(1)

这是我创建csv行数据的方法:

def get_row_data(model, row):    """Get a row of csv data from an object"""    #Create a temporary csv handle    csv_handle = cStringIO.StringIO()    #create the csv output object    csv_output = csv.writer(csv_handle)    value_list = []     for field in model._meta.fields:        #if the field is a related field (ForeignKey, ManyToMany, OneToOne)        if isinstance(field, RelatedField):            #get the related model from the field object            related_model = field.rel.to            for key in row.__dict__.keys():                #find the field in the row that matches the related field                if key.startswith(field.name):                    #Get the unicode version of the row in the related model, based on the id                    try:                        entry = related_model.objects.get(                            id__exact=int(row.__dict__[key]),                            )                    except:                        pass                    else:                        value = entry.__unicode__().encode("utf-8")                        break        #if it isn''t a related field        else:            #get the value of the field            if isinstance(row.__dict__[field.name], basestring):                value = row.__dict__[field.name].encode("utf-8")            else:                value = row.__dict__[field.name]        value_list.append(value)    #add the row of csv values to the csv file    csv_output.writerow(value_list)    #Return the string value of the csv output    return csv_handle.getvalue()

答案1

小编典典

这是一些简单的代码,将流式传输CSV;您可能可以从这里转到您需要做的一切:

import cStringIO as StringIOimport csvdef csv(request):    def data():        for i in xrange(10):            csvfile = StringIO.StringIO()            csvwriter = csv.writer(csvfile)            csvwriter.writerow([i,"a","b","c"])            yield csvfile.getvalue()    response = HttpResponse(data(), mimetype="text/csv")    response["Content-Disposition"] = "attachment; filename=test.csv"    return response

这只是将每一行写入内存文件中,读取并产生该行。

此版本对于生成批量数据更有效,但是在使用它之前请务必了解以上内容:

import cStringIO as StringIOimport csvdef csv(request):    csvfile = StringIO.StringIO()    csvwriter = csv.writer(csvfile)    def read_and_flush():        csvfile.seek(0)        data = csvfile.read()        csvfile.seek(0)        csvfile.truncate()        return data    def data():        for i in xrange(10):            csvwriter.writerow([i,"a","b","c"])        data = read_and_flush()        yield data    response = HttpResponse(data(), mimetype="text/csv")    response["Content-Disposition"] = "attachment; filename=test.csv"    return response

c# – 如何在asp.net中流式传输视频内容?

c# – 如何在asp.net中流式传输视频内容?

我有以下代码下载视频内容:
WebRequest wreq = (HttpWebRequest)WebRequest.Create(url);
using (HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse())
using (Stream mystream = wresp.GetResponseStream())
{
  using (BinaryReader reader = new BinaryReader(mystream))
  {
    int length = Convert.ToInt32(wresp.ContentLength);
    byte[] buffer = new byte[length];
    buffer = reader.ReadBytes(length);

    Response.Clear();
    Response.Buffer = false;
    Response.ContentType = "video/mp4";
    //Response.BinaryWrite(buffer);
    Response.OutputStream.Write(buffer,buffer.Length);
    Response.End();
  }
}

但问题是整个文件在播放之前下载.如何让它流式传输和播放,因为它仍在下载?还是由客户/接收者应用来管理?

解决方法

您正在将整个文件读入单个缓冲区,然后一次发送整个字节数组.

您应该在while循环中读入较小的缓冲区.

例如:

byte[] buffer = new byte[4096];

while(true) {
    int bytesRead = myStream.Read(buffer,buffer.Length);
    if (bytesRead == 0) break;
    Response.OutputStream.Write(buffer,bytesRead);
}

Django 流式响应中文csv样例

Django 流式响应中文csv样例

在Django里,流式响应StreamingHttpResponse是个好东西,可以快速、节省内存地产生一个大型文件。

目前项目里用于流式响应的一个是Eventsource,用于改善跨系统通讯时用户产生的慢速的感觉。这个不细说了。

还有一个就是生成一个大的csv文件。

当Django进程处于gunicorn或者uwsgi等web容器中时,如果响应超过一定时间没有返回,就会被web容器终止掉,虽然我们可以通过加长web容器的超时时间来绕过这个问题,但是毕竟还是治标不治本。要根本上解决这个问题,Python的生成器、Django框架提供的StreamingHttpResponse这个流式响应很有帮助

而在csv中,中文的处理也至关重要,要保证用excel打开csv不乱码什么的。。为了节约空间,我就把所有代码贴到一起了。。实际使用按照项目的规划放置哈

上代码:

pythonfrom __future__ import absolute_import
import csv
import codecs
import cStringIO


class Echo(object):

    def write(self, value):
        return value

class UnicodeWriter:

    """
    A CSV writer which will write rows to CSV file "f",
    which is encoded in the given encoding.
    """

    def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
        # Redirect output to a queue
        self.queue = cStringIO.StringIO()
        self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
        self.stream = f
        self.encoder = codecs.getincrementalencoder(encoding)()

    def writerow(self, row):
        self.writer.writerow([handle_column(s) for s in row])
        # Fetch UTF-8 output from the queue ...
        data = self.queue.getvalue()
        data = data.decode("utf-8")
        # ... and reencode it into the target encoding
        data = self.encoder.encode(data)
        # write to the target stream
        value = self.stream.write(data)
        # empty queue
        self.queue.truncate(0)
        return value

    def writerows(self, rows):
        for row in rows:
            self.writerow(row)






from django.views.generic import View
from django.http.response import StreamingHttpResponse

class ExampleView(View):
    headers=[''一些'',''表头'']
    def get(self,request):
        result = [[''第一行'',''数据1''],
                  [''第二行'',''数据2'']]
        echoer = Echo()
        writer = UnicodeWriter(echoer)
        def csv_itertor():
                yield codecs.BOM_UTF8
                yield writer.writerow(self.headers)
                for column in result:
                    yield writer.writerow(column)

        response = StreamingHttpResponse(
            (row for row in csv_itertor()),
            content_type="text/csv;charset=utf-8")
        response[''Content-Disposition''
                 ] = ''attachment;filename="example.csv"''
        return response

django 生成和下载CSV文件

django 生成和下载CSV文件

一、生成小型的csv文件

1、直接处理数据

from django.http import HttpResponse
import csv

# 简单生成下载csv文件
def down_csv_1(request):
    # 指定返回的类型为csv
    response = HttpResponse(content_type=''text/csv'')
    # 添加返回头说明如何处理这个返回对象,并指明文件名。attachment:作为附件的形式进行下载
    response[''Content-Disposition''] = "attachment;filename=''test.csv''"
    # 创建写的对象
    writer = csv.writer(response)
    # 写入一行数据
    writer.writerrow([''username'',''age''])
    # 写入下一行数据
    writer.writerrow([''Xsan'',20])
    return response


2、使用模版处理要下载的数据:

(1)在templates文件夹下面创建处理数据的模版文件比如test.txt。
test.txt文件

{# 一定要将循环体和for语句写在一行,否则会出现空行的情况 #}
{% for row in rows %}{{ row.0 }},{{ row.1 }}
{% endfor %}

(2)在视图函数中引用

views.py
from django.http import HttpResponse
from django.template import loader
import csv

#使用模版处理要下载的数据
def down_csv_2(request):
    # 指定返回的类型为csv
    response = HttpResponse(content_type=''text/csv'')
    # 添加返回头说明如何处理这个返回对象,并指明文件名。attachment:作为附件的形式进行下载
    response[''Content-Disposition''] = "attachment;filename=''test.csv''"
    # 创建要下载的数据,此时要和模版结合起来
    context = {
        ''rows'':[
        [''username'',''age''],
        [''Xsan'',20]]
    }
    # 引用自定义的模版
    template = loader.get_template(''test.txt'')
    # 将要下载的数据使用模版格式化
    csv_template = template.render(context)
    # 将处理好的数据渲染至上下文
    response.content = csv_template
    return response

二、生成大型的csv文件
上面我们讲了生成一个小的csv文件,如果要生成大型的csv文件该如何做呢?上面的代码可能会发生超时的情况(服务器要生成一个大型的csv文件,需要的时间可能会超过浏览器默认的时间)。这时候我们需要借助一个类StreamingHttpResponse对象,这个对象能将响应的数据作为一个流返回给客户端,而不是作为一个整体返回。
关于StreamingHttpResponse:
这个类时专门用来处理流数据的。使得在处理大型文件的时候,不会因为服务器处理时间过长而导致连接超时。这个类不是继承自HttpResponse,并且跟HttpResponse对比有以下几点区别:
1、这个类没有属性content,相反是streaming_content。
2、这个类的streaming_content必须是一个可迭代对象。
3、这个类没有write方法,如果给这个类的对象写入数据将会报错。
注意:StreamingHttpResponse会启动一个进程来和客户端保持长连接,所以会很消耗资源。所以如果不是特殊要求,尽量少用这种方法。

    views.py
    from django.http import HttpResponse,StreamingHttpResponse 
    from django.template import loader
    import csv
    
    def large_csv_view(request):
        response = StreamingHttpResponse(content_type=''text/csv'')
        response[''Content-Disposition''] = "attachment;filename=''large.csv''"
        rows = ("Row {},{}\n".format(row,row) for row in range(0,10000))
        response.streaming_content = ("username,age\n","Xsan,20\n")
        return response

Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?

Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?

如何解决Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField??

大家。希望你做得很好。我想通过预先说明我是 AWS 的真正新手来开始这个问题。现在,我正在与一位已经拥有更多 Web 开发经验的朋友一起开发 Django 应用程序,他已经在 AWS 中设置了所有内容,也就是说,我们已将大部分文件上传到那里,正在运行一个暂存应用程序和其他一些配置。

我正在研究将一些数据库数据从我们的网络应用程序转换为 CSV 文件并将其上传到云端的后端实现。

基本上,我们有一个端点,用户可以在其中从站点的另一个 URL 请求数据,我们的应用程序会将数据转换为 .CSV 文件,将其导出到 S3 并同时 strong> 将其保存在模型的 FileField 上。然后,一旦文件被上传,用户将在其电子邮件中收到它。由于文件可能非常大,因此最大的问题是:如何将 .CSV 文件流式传输到 S3 Bucket 并让 Django 将其保存到模型的 FileField 属性中?这是我的参考代码(这是迄今为止在本地创建 .csv 的唯一方法):

--------------------------/// MODEL // ---------------------------------------------
class Export(models.ModelModel):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,)
    file = models.FileField(upload_to=''s3://buckect/uploads/'',blank=True,null=True)
# Some other fields that don''t matter

-----------------------------///-EXPORT FUNCTION -----------------------------------
from io import StringIO
import csv
from smart_open import open

with open(''s3://buckect/uploads/test.csv'',''a+'') as fout:
        csv_buffer = StringIO()
        csv_writer = csv.writer(csv_buffer,escapechar='' '',quoting=csv.QUOTE_NONE)
        data = data_generator(export_object.id)
        for row in data:
            csv_writer.writerow([row])
        csv_file = csv_buffer.getvalue()
        fout.write(csv_file)
        export_object.file.save(''s3://buckect/test.csv'',fout)

我还没有测试它,因为我仍然无法访问 S3,但这在我看来是因为它会将文件上传到 S3 两次,不是吗?

我确实在本地尝试过,是的,确实在 open() 创建了 .CSV 文件并保存在模型中。但基于我对 S3 的有限了解,当您将其设置为存储时,我不太确定 Django 的 FileField 的行为如何。

另外,有人告诉我使用 Smart_open,据说它可以将我的文件流式传输到 S3。但我只发现 one similar usecase 并没有真正解释它是否或如何流式传输文件,而且它也是一个非常老的帖子。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

今天的关于在Django中流式传输CSV文件django视频流传输的分享已经结束,谢谢您的关注,如果想了解更多关于c# – 如何在asp.net中流式传输视频内容?、Django 流式响应中文csv样例、django 生成和下载CSV文件、Django、CSV、FileField 和 S3 - 如何将 CSV 文件流式传输到 S3 Bucket 并将其保存到 Django 模型的 FileField?的相关知识,请在本站进行查询。

本文标签: