Использование flask для запуска команды SQL и вывода результатов в формате CSV загрузка

#python #sql #flask

#python #sql #flask

Вопрос:

идея:

  • возьмите идентификаторы из ввода html
  • используйте идентификаторы для запуска sql и возврата соответствующих имен пользователей
  • загружайте выходные данные в формате csv во внешнем интерфейсе при нажатии кнопки «загрузить»

HTML

 Enter comma delimited ids <input type="text" id="text1" name="text1"><br><br>
<a href="/getPlotCSV">download</a>
  

python

 @app.route("/getPlotCSV", methods=['GET','POST'])
def getPlotCSV():
    text1 = request.form['text1']
    result = {}

    a = []
    x = []

    a.extend([str(x) for x in text1.split(",")])
    format_strings = ','.join(['%s'] * len(a))
    cursor = cnxn.cursor()
    sql = "SELECT DisplayName FROM dbo.[Users] where id IN ({seq})".format(
        seq=','.join(['?'] * len(a)))
    cursor.execute(sql,a)
    for row, in cursor:
        x.append(row)

    csv = x

    return Response(
        csv,
        mimetype="text/csv",
        headers={"Content-disposition":
                 "attachment; filename=myplot.csv"})
  

sql и ввод работают, потому что я тестировал его отдельно без загрузки csv, и он возвращает правильные данные. Ошибка, которую я получаю на данный момент, — «400 Неверный запрос: Браузер (или прокси) отправил запрос, который этот сервер не смог понять. » Ошибка ключа: ‘text1’

чего мне здесь не хватает?

Ответ №1:

Это KeyError потому, что вы фактически не передали значение text1 своему getPlotCSV маршруту. Ссылка на HTML-странице также не будет передавать данные вместе с ней. Вместо этого вам нужно использовать форму со страницей действий, например:

 <form action="/getPageCSV" method="post">
  Enter comma delimited ids: <input type="text" id="text1" name="text1">
  <input type="submit" name="Submit" id="submit">
</form>
  

Затем эти значения должны быть переданы URL-адресу в атрибуте формы action , в данном случае вашему getPageCSV . Это не обязательно должно быть POST, я только что сделал это в качестве примера.

Затем, когда ваш маршрут получит данные:

 @app.route('/getPageCSV')
def getPlotCSV():
    if request.method == "POST": #in other words, if the form is being submitted
      text1 = request.form.get('text1') #use dict.get in case it isn't there
      
      # your code 

      csv = x
      return redirect(url_for('getPlotCSV')) #this time a get method
    return Response(
        csv,
        mimetype="text/csv",
        headers={"Content-disposition":
                 "attachment; filename=myplot.csv"})
  

Вышеуказанное не будет работать без добавления вашего собственного способа перемещения данных / csv после обработки при перенаправлении пользователя. Вы можете сделать это как заголовок запроса, сохранить его в хранилище сеанса или даже поместить в строку запроса, это зависит от вас, но вы должны иметь возможность отображать результаты вашего POST-процесса в запросе GET при перенаправлении пользователя.