在Flask会话中保留用于分析的上载数据

2024-04-19 19:50:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我非常挣扎于一个概念,希望有人能提供一个代码实现的建议。我的flask应用程序中嵌入了以下路径。经过几天的研究,我想我现在明白了问题的本质。我已经根据下面评论中的建议修改了我的代码

在现在的web应用程序中,数据框列的名称填充一个下拉菜单,用户可以选择其中一个变量并单击“显示”。然后,变量名打印到屏幕上,这样我就知道表单中的帖子正在与flask应用程序中的函数通信

我想做的是为上传的文件创建一个临时版本,这样只要web会话打开(或者在新文件上传时被覆盖),该文件就会存在。然后,用户从下拉菜单中选择一个变量,并计算该变量的平均值(该部分在下面的代码中暂时注释掉,但您可以看到我尝试了什么)

如果用户读入一个新文件,那么同样的过程也会发生在这个新文件上

谢谢你的建议和支持

from flask import Flask, render_template, request
import numpy as np
from scipy.stats import binom  
from scipy.optimize import minimize
from scipy.stats import norm 
from scipy import optimize 
from pyodbc import connect 
import pandas as pd 
import os
import tempfile


app = Flask(__name__)
    @app.route('/dataTools', methods=['POST', 'GET'])
def data_tools_upload():
    tempfile_path = tempfile.NamedTemporaryFile().name
    if request.files:
        df = pd.read_csv(request.files.get('file'))
        #tempfile_path = tempfile.NamedTemporaryFile().name 
        df.to_csv(tempfile_path)
    if os.path.exists(tempfile_path):
        orig_df = pd.read_csv(tempfile_path)
        vars = list(orig_df.columns)
        var2use = request.form.get("var2use")
        #indx = vars.index(var2use)
        #df[vars[indx]].mean()
        mean = orig_df[vars[4]].mean()
        dims = orig_df.shape
        message = 'You have data! There are %s rows and %s columns and the variable %s has mean %s' % (dims[0],dims[1],vars[4],round(mean,3))
        table = orig_df.head(10).to_html(classes='data', header = "true")
        return render_template('upload.html', tables = [table], message = message, vars = vars, var_name = var2use)
    var2use = request.form.get("var2use")
    return render_template('upload.html', var_name = var2use, message = "What happened?") 
if __name__ == '__main__':
    app.run(debug=True)

然后是以下HTML位(upload.HTML):

{% extends "layout.html" %}    
{% block body %}

<h3> Read in a data file </h3>

<br>

<form method=post enctype=multipart/form-data>
    <input type=file name=file class = "btn btn-outline-secondary">
    <input type=submit value=Upload class = "btn btn-outline-secondary">
</form>

<br>    

<form class="form-inline" action = "{{url_for('data_tools_upload')}}" method = "POST">
    <select type = "text" name="var2use" class="custom-select mr-sm-1">
        {% for var in vars %}
            <option value= "{{ var }}" SELECTED>{{ var }}</option>"
        {% endfor %}
    </select>
        <button class = "btn btn-primary"> Show </button>
</form>


<center>
    <h1>
    {{message}}
    {{name}}
    </h1>
    <br>
        <small>
        {% for table in tables %}
                    {{ table|safe }}
        {% endfor %}

        {% endblock %}
        </small>
</center>

Tags: pathnamefromimportformdfdatarequest
1条回答
网友
1楼 · 发布于 2024-04-19 19:50:07

您需要保存文件才能使用它(该代码在我的应用程序中非常有效):

        f = request.files['file']
        tmp_filename = '/tmp/my_tmp_file.csv'
        f.save(tmp_filename)
        pd.read_csv(tmp_filename)

以下是有关Flask文件上载的详细文档: https://flask.palletsprojects.com/en/1.1.x/patterns/fileuploads/

下面是您案例的完整示例。我认为您可能在以下三个方面存在问题:

  1. 由于表单类型(应为“多部分/表单数据”)而上载文件
  2. 由于文件大小而上载(请尝试我的示例)
  3. 处理表单时,空文件将覆盖您的表单(请参见我的“csv\u文件上传”示例)

Python(csv\u test.py):

from flask import Flask, render_template, request
import pandas as pd
import os

app = Flask(__name__, static_url_path='')

@app.route('/', methods=['GET', 'POST'])
def index():
    data = {}
    tmp_filename = '/tmp/csv_test.csv'
    if request.files:
        csv_file_uploaded = request.files.get('file')
        if csv_file_uploaded:
            f = request.files['file']
            f.save(tmp_filename)
    if os.path.exists(tmp_filename):
        df = pd.read_csv(tmp_filename)
        data['columns'] = ', '.join(df.columns)
        col_selected = request.form.get('col_selected')
        print(col_selected)
        data['col_selected'] = col_selected
        if col_selected:
            mean = df.get(col_selected).mean()
            data['mean'] = mean
    return render_template('csv_test.tpl', data=data)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0')

烧瓶模板(csv\u test.tpl):

<html><head><title>CSV TEST</title></head>
    <body><h1>CSV TEST</h1>
      {% if data %}
          <div>Columns of the uploaded file: <strong>{{ data.columns }}</strong></div>
          <div>Selected column: <strong>{{ data.col_selected }}</strong></div>
          <div>Mean of the selected = <strong>{{ data.mean }}</strong></div>
      {% endif %}
      <fieldset>
         <form enctype="multipart/form-data" action="" method="post">
            <h2>Provide some CSV with first column in numbers and/or column name</h2>
            <div>File{% if data.columns %} (UPLOADED){% endif %}: <input id="file" type="file" name="file"/></div>
            <div>Column: <input id="col_selected" type="text" name="col_selected" value="{{ data.col_selected }}"/></div>
            <div><input id="submit" type="submit" value="SUBMIT"/></div>
         </form>
      </fieldset>
</body></html>

CSV文件(123.CSV)-使用它测试表单:

col1,col2
1,2
2,3
3,4
5,6

相关问题 更多 >