2017-06-01 64 views
1

我有一個函數視圖,它使用xlsxwriter創建一個報告,它使用StringIO作爲緩衝區即時創建,最後通過HttpResponse發送。
它使用本地服務器運行良好。Django - Heroku - 服務動態大文件超時

問題是,在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

回答

0

恕我直言,你應該遵循一種完全不同的方法在這種情況下。 由於您生成的文件相當大,因此超時錯誤導致系統掛起是正常的。

你可以做的是部署後臺任務隊列,如Celery或DjangoRQ。因此,您將獲得使用用戶數據創建此文件的後臺任務,然後您可以讓用戶知道它已準備就緒,如通知或電子郵件。

如果您需要關於如何可以做這樣的事情更多的細節,讓我知道,我可以幫助:)

+0

我在用芹菜和Redis的一個後臺進程,創建該文件並保存它一直在努力在臨時目錄中,然後在文件準備就緒時通知用戶。但是使它在Heroku中運行的部分是一個痛苦。你有什麼樣的指導來做到這一點? –

+0

有沒有你卡住的特定部分?請稍微精確一下,你需要什麼類型的信息,我會看看有關類似案例的指南 –

+0

我現在所有的後臺工作都與redis和芹菜一起工作,但我將自己的檔案保存在亞馬遜S3並將URL返回給用戶以開始下載。這是行得通的,但不是我想要的,因爲我需要將臨時存檔或在內存中生成,以及在工作或後臺進程中的所有內容。 –