Flask приложение выдает ошибку при развертывании на heroku и попытке открыть файл excel - PullRequest
0 голосов
/ 24 февраля 2020

У меня есть приложение Flask, и в приложении у меня есть представление, где я использую xlsxwriter для записи и сохранения Excel файла. Когда я запускаю приложение локально, оно работает отлично. Когда я его развертываю, все представления работают, кроме той, где я пишу файл Excel, это дает мне Ошибка 500. В логах я обнаружил, что ошибка в том, что я пытаюсь запустить файл с функцией это только для windows, может кто-нибудь сказать мне, как запустить файл или загрузить его? Мне не нужно хранить его в базе данных или облачном хранилище, просто чтобы его можно было распечатать или загрузить немедленно. Ps, пожалуйста, извините, если я сделал ошибку, задавая этот вопрос.

@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 с данными из базы данных, а затем я хочу, чтобы пользователь распечатал ее или загрузить его на свой компьютер.

Ответы [ 2 ]

0 голосов
/ 26 февраля 2020

Я хочу создать электронную таблицу 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))

Как отметила Тин, Файловая система Heroku эфемерна , поэтому PDF-файлы на вашем сервере исчезнут. Если все в порядке, вы, вероятно, не столкнетесь с таким большим количеством проблем. Если кто-то запрашивает PDF за до перезапуска dyno, у вас могут возникнуть некоторые проблемы, но он может запросить его снова.

0 голосов
/ 24 февраля 2020

Вы жестко закодировали путь:

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 есть своя эфемерная файловая система с бесплатной sh копией последнего развернутого кода. В течение срока службы динамометрического стенда его работающие процессы могут использовать файловую систему в качестве временной блокнота , но записанные файлы не будут видны процессам в любом другом динамометрическом стенде, и любые записанные файлы будут отброшены момент, когда динамо остановлено или перезапущено. Например, это происходит каждый раз, когда динамо заменяется из-за развертывания приложения, и примерно один раз в день как часть обычного управления динамо.

Динамо перезапускается один раз в день. Это означает, что ваши данные будут потеряны. Вам нужна правильная база данных или используйте другое решение для хостинга.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...