【问题标题】:Flask app gives error when deployed on heroku and trying to open excel fileFlask 应用程序在 Heroku 上部署并尝试打开 excel 文件时出错
【发布时间】:2020-02-24 19:03:16
【问题描述】:

我有 Flask 应用程序,在应用程序中,我有一个视图,我正在使用 xlsxwriter 编写和保存 Excel 文件。当我在本地运行应用程序时,它可以完美运行。当我部署它时,除了我正在编写 Excel 文件的视图之外,所有视图都可以工作,它给了我 错误 500。 在日志中,我认为错误是我正在尝试使用仅适用于Windows的功能,有人可以告诉我如何启动文件或下载它吗?我不需要将它存储在数据库或云存储中,只需立即打印或下载即可。 P.s 如果我问这个问题有误,请原谅。

@app.route("/proverka", methods=['GET', 'POST'])
def proverka():
    stream = artikli.query.all()

    mah_id=db.session.query(db.func.max(info.id)).first()
    s=info.query.filter_by(id=mah_id[0]).first()
    if request.method=='POST':

        workbook = xlsxwriter.Workbook('ISPRATNICI\\{}, {}.xlsx'.format(s.id, s.ime))
        brojac=9
        worksheet = workbook.add_worksheet()
        #NASLOV
        merge_format = workbook.add_format({'align': 'center', "size": "30"})
        worksheet.merge_range('A1:F1',"„Оска-Пром“ Дооел Виница" , merge_format)
        #informacii za firmata
        worksheet.write("B3", "ул. Страшо Пинџур бр.2")
        worksheet.write("B4", "033/363-841")
        worksheet.write("B5", "071-229-482")
        #informacii za kupuvacot
        podatoci_format = workbook.add_format({'align': 'center', "size": "13"})
        worksheet.merge_range('D3:E3',s.ime, podatoci_format)
        worksheet.merge_range('D4:E4',s.kontakt, podatoci_format)
        worksheet.merge_range('D5:E5', s.ulica, podatoci_format)
        #Ispratnica br.
        ispratnica_format = workbook.add_format({'align': 'center', "size": "20"})

        worksheet.merge_range('A8:F8',"Испратница бр. {}".format(s.id) , ispratnica_format)

        #kategorii  
        meni_format = workbook.add_format({'align': 'center', "size":"14", "border":1})
        vkupno=workbook.add_format({"border":1,'align': 'center', "size":"14",  })
        worksheet.write("A9", "р.бр.", meni_format)
        worksheet.write("B9", "Назив на артикл", meni_format)
        worksheet.write("C9", "Количина", meni_format)
        worksheet.write("D9", "Цена", meni_format)
        worksheet.write("E9", "Износ", meni_format)
        worksheet.write("D39", "Вкупно", vkupno)

        worksheet.set_column("A:A", 7.43)
        worksheet.set_column("B:B", 32)
        worksheet.set_column("C:E", 12)
        worksheet.set_row(7, 38)

        #tabeli granica
        granica=workbook.add_format({"border":1})
        #artikli
        for i in stream:
            worksheet.write(brojac, 0, i.id, granica)
            worksheet.write(brojac, 1, i.model, granica)
            worksheet.write(brojac, 2, i.kolicina, granica)
            worksheet.write(brojac,3, i.cena, granica)
            worksheet.write(brojac, 4, i.vkupno, granica)
            brojac+=1
            saldo=workbook.add_format({"align":"center", "size":"16", "border":2})
            worksheet.write_formula('E39', '=SUM(E9:E38)', saldo)
        workbook.close()

        for i in stream:
            kolicini_za_menjanje=magacin.query.filter_by(model=i.model).first()
            print(kolicini_za_menjanje.kolicina)
            nova_kol=kolicini_za_menjanje.kolicina-i.kolicina
            print(nova_kol)
            kolicini_za_menjanje.kolicina = nova_kol
            db.session.commit()

        #IZBRISI ARTIKLI
        brisi=artikli.query.all()
        for i in brisi:
            artikli.query.filter_by(id=i.id).delete()
            db.session.commit()
        os.startfile("C:\\Users\\Nenad\\Desktop\\magacin vs\\ISPRATNICI\\{}, {}.xlsx".format(s.id, s.ime))
        return redirect(url_for("home"))

    return render_template("proverka.html", stream=stream, s=s)

日志:

2020-02-22T16:10:18.789403+00:00 app[web.1]: [2020-02-22 16:10:18,787] ERROR in app: Exception on /proverka [POST]
2020-02-22T16:10:18.789405+00:00 app[web.1]: Traceback (most recent call last):
2020-02-22T16:10:18.789406+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app  
2020-02-22T16:10:18.789407+00:00 app[web.1]: response = self.full_dispatch_request()
2020-02-22T16:10:18.789408+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request
2020-02-22T16:10:18.789408+00:00 app[web.1]: rv = self.handle_user_exception(e)
2020-02-22T16:10:18.789408+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception
2020-02-22T16:10:18.789409+00:00 app[web.1]: reraise(exc_type, exc_value, tb)
2020-02-22T16:10:18.789409+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise 
2020-02-22T16:10:18.789410+00:00 app[web.1]: raise value
2020-02-22T16:10:18.789410+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request
2020-02-22T16:10:18.789411+00:00 app[web.1]: rv = self.dispatch_request()
2020-02-22T16:10:18.789411+00:00 app[web.1]: File "/app/.heroku/python/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request
2020-02-22T16:10:18.789412+00:00 app[web.1]: return self.view_functions[rule.endpoint](**req.view_args)
2020-02-22T16:10:18.789413+00:00 app[web.1]: File "/app/app.py", line 206, in proverka
2020-02-22T16:10:18.789413+00:00 app[web.1]: os.startfile("C:\\Users\\Nenad\\Desktop\\magacin vs\\ISPRATNICI\\{}, {}.xlsx".format(s.id, s.ime))
2020-02-22T16:10:18.789414+00:00 app[web.1]: AttributeError: module 'os' has no attribute 'startfile'
2020-02-22T16:10:18.790447+00:00 app[web.1]: 10.102.224.122 - - [22/Feb/2020:16:10:18 +0000] "POST /proverka HTTP/1.1" 500 290 "https://oska-prom.herokuapp.com/proverka" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
2020-02-22T16:10:18.790269+00:00 heroku[router]: at=info method=POST path="/proverka" host=oska-prom.herokuapp.com request_id=4012bbf1-c4ec-46e9-bfd0-5d8fdb23c23d fwd="77.29.30.58" dyno=web.1 connect=0ms service=43ms status=500 bytes=470 protocol=https
2020-02-22T16:10:19.267659+00:00 heroku[router]: at=info method=GET path="/proverka" host=oska-prom.herokuapp.com request_id=ee6b17a9-a2b0-4b77-adaf-d967c48ace12 fwd="77.29.30.58" dyno=web.1 connect=0ms service=15ms status=200 bytes=2539 protocol=https
2020-02-22T16:10:19.269189+00:00 app[web.1]: 10.102.224.122 - - [22/Feb/2020:16:10:19 +0000] "GET /proverka HTTP/1.1" 200 2377 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"

编辑 我上传了出现错误的视图代码。您能否建议另一种方法,替换硬编码路径或如何下载文件。

我想做的是使用数据库中的数据创建 excel 电子表格,然后我希望用户将其打印或下载到他的计算机上。

【问题讨论】:

  • 这是your last question 的完全相同的副本,您收到的答案与下面的新答案大致相同,但更详细。这个答案有什么问题?请don't repost the same question.
  • 在另一个问题中,我没有发布代码,我的问题被关闭了。在这里,我试图避免这个错误。
  • 所以删除旧的。如果旧问题仍然存在,您仍然不应该再次重新发布相同的问题。正确的做法是修复旧的并希望它重新打开。无论如何,再次,您上次得到了一个您似乎没有阅读过的有用的答案。请这样做。你不能在 Heroku 上使用 Windows 风格的路径,你不能访问你客户端的文件系统,不能使用os.startfile。你想做什么
  • 我想做的是使用数据库中的数据创建 excel 电子表格,然后我希望用户打印或下载到他的计算机上。这可能吗,如果可以,你会礼貌地告诉我怎么做吗?

标签: python flask heroku


【解决方案1】:

我想做的是用数据库中的数据创建excel电子表格,然后我希望用户打印或下载到他的电脑上

os.startfile() 绝不会这样做。

它可能看起来像它在开发中,但这只是因为您的客户端和服务器在同一台机器上运行。如果您在 Windows 上托管您的代码(os.startfile() 存在)并从另一台机器连接到它,您的 服务器 将尝试打开该文件。它根本不会显示在客户端上。

摆脱

os.startfile("C:\\Users\\Nenad\\Desktop\\magacin vs\\ISPRATNICI\\{}, {}.xlsx".format(s.id, s.ime))

完全。

改为以send_file 结束您的函数:

from flask import send_file

@app.route("/proverka", methods=['GET', 'POST'])
def proverka():
    # ...
    send_file('ISPRATNICI\\{}, {}.xlsx'.format(s.id, s.ime))

正如 Tin 所说,Heroku's filesystem is ephemeral 所以您服务器上的 PDF 将消失。如果没问题,您可能不会遇到太多问题。如果有人在测功机重新启动之前只是请求 PDF,您可能会遇到一些问题,但他们应该能够再次请求。

【讨论】:

    【解决方案2】:

    您对路径进行了硬编码:

    os.startfile("C:\\Users\\Nenad\\Desktop\\magacin vs\\ISPRATNICI\\{}, {}.xlsx".format(s.id, s.ime))
    

    使用os,您可以构建相对路径,使其在 Windows 和 Linux 上都可以使用。我们需要查看源代码来建议您如何正确构建路径。

    话虽如此,您似乎正在将数据写入您可能稍后使用的文件。 Heroku 适合这个。

    https://devcenter.heroku.com/articles/dynos#ephemeral-filesystem

    每个 dyno 都有自己的临时文件系统,带有一个新的副本 最近部署的代码。在测功机的生命周期中,它的运行 进程可以将文件系统用作临时暂存器,但不能 写入的文件对任何其他测功机中的进程可见,并且 当测功机停止或 重新启动。例如,任何时候更换测功机时都会发生这种情况,因为 应用程序部署和大约一天一次作为正常的一部分 测功机管理。

    Dynos 每天重新启动一次。这意味着您的数据将丢失。您需要合适的数据库或使用其他托管解决方案。

    【讨论】:

      猜你喜欢
      • 2015-03-17
      • 2020-10-21
      • 2019-11-27
      • 2019-04-03
      • 2019-11-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多