Django - Heroku - 提供动态大文件超时

时间:2017-06-01 16:10:18

标签: python django heroku large-data

我有一个使用xlsxwriter创建报告的功能视图,它是使用StringIO作为缓冲区动态创建的,最后通过HttpResponse发送。
它使用本地服务器很好。

问题是,在Heroku上,几秒钟后(文档提到30秒超时且无法修改)服务器挂起并重新启动Web进程,并将错误作为响应。

最好的方法是什么?

  • 在内存中动态创建xmlx文件
  • 将整个文件提供给客户端。
  • 阻止服务器因长时间运行而挂出

这是我正在使用的一段代码:

def reporte_usuarios(request):
    from xlsxwriter.workbook import Workbook
    try:
        import cStringIO as StringIO
    except ImportError:
        import StringIO

    # create a workbook in memory
    output = StringIO.StringIO()

    workbook = Workbook(output)

    bold = workbook.add_format({'bold': True})

    # get the data
    from django.db.models import Count
    usuarios = User.objects.filter(....... # all filter stuff

    for usr in usuarios:
        if usr.activos > 0:

            # create a workbook sheet every User registered
            ws = workbook.add_worksheet(u'%s' % usr.username)

            # some relevant user data
            ws.write(1, 1, u'USUARIO: %s' % usr.username)
            ...

            # get rows for user
            log = LogActivos.objects.filter(usuario=usr).select_related('activo__unidad__id', 'activo__unidad__nombre', 'activo__nombre')

            # write headers
            ws.write(3, 0, u'FECHA', bold)
            ...
            sig_fila = 4  #starting row for data (after headers)
            for l in log:
                # write all data
                ws.write(sig_fila, 0, u'%s' % l.fecha)
                ...
                sig_fila += 1
    # close the workbook
    workbook.close()
    # go to the beginning of the buffer
    output.seek(0)
    # response using the buffer
    response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename="ACTIVOS_USUARIOS__%s.xlsx"' % datetime.now().strftime("%Y%m%d_%H%M")
    return response

注意:我在Heroku上使用Gunicorn,django 1.9.13和python 2.7.11

1 个答案:

答案 0 :(得分:0)

恕我直言,在这种情况下你应该采用完全不同的方法。 当您生成一个相当大的文件时,由于超时错误,系统挂起是正常的。

您可以做的是部署后台任务队列,如Celery或DjangoRQ。有了这个,您将获得一个后台任务,使用您的用户数据创建此文件,然后您可以通过任何方式让您的用户知道它已准备就绪,如通知或电子邮件。

如果您需要有关如何执行此类操作的更多详细信息,请告诉我,我可以提供帮助:)