Flask中如何使用函数生成的DataFrame返回CSV下载响应及参数报错解决
问题原因
- 你定义的
csv_download视图函数声明了必填位置参数CSV,但路由@app.route("/csv_download", methods=['GET'])没有配置对应的路径参数,当用户点击下载按钮时,浏览器直接发起GET请求调用该视图,Flask没有可传入的参数,因此触发参数缺失报错。 - 你在
result函数内部直接调用csv_download(csv_data)属于Python函数的本地调用,确实可以正常执行,但这个调用的返回值没有被作为响应返回给用户,属于无效调用,不会触发下载行为。
修复方案
以下是低改造成本的通用方案,无需大幅调整原有逻辑:
第一步:调整后端视图逻辑
把CSV生成逻辑抽为公共方法,csv_download视图内部自行调用获取数据,去掉外部传参依赖,修改后代码如下:
# 抽离公共CSV生成逻辑,避免重复写代码 def get_dataset_and_csv(): mapping_query = """select * from test""" Query = pd.read_sql_query(mapping_query, conn) dataset = pd.DataFrame(Query) dataset.set_index('itemID', inplace=True) csv_data = dataset.to_csv(index=False, encoding='utf-8') return dataset, csv_data @app.route("/result", methods=['POST','GET']) def result(): from datetime import datetime start_time = datetime.now().replace(microsecond=0) # 调用公共方法获取数据集和csv dataset, csv_data = get_dataset_and_csv() # 删掉原本的无效调用csv_download(csv_data) Size_mapped = len(dataset) print('Size Mapped with YP :', Size_mapped) flash(Size_mapped) results = list(dataset.values.tolist()) fieldnames = dataset.columns.values end_time = datetime.now().replace(microsecond=0) elapsed_time_known = end_time - start_time print("\n") print('>>>>> Time elapsed from beginning: <<<<<', elapsed_time_known) return render_template('result.html', times=[elapsed_time_known], results=results, fieldnames=fieldnames, zip=zip) @app.route("/csv_download", methods=['GET']) def csv_download(): # 内部直接获取csv数据,不需要外部传参 _, csv_data = get_dataset_and_csv() print("\n") print('this is CSV file:', csv_data) response = Response(csv_data,mimetype='text/csv') response.headers.set("Content-Disposition", "attachment", filename="Export_Merchant_Validator_Tool.csv") return response
第二步:简化前端表单代码
GET请求不需要multipart/form-data编码类型,删掉冗余属性即可:
<form style="margin-left: 38%" method="GET" action="/csv_download"> <button style="height: 50%; width: 38%; color: white; background-color: #696969; border-color: #696969; " type="submit" value="Submit" class="btn btn-primary btn-lg" > Download dataset as csv </button> </form>
如果不想重复查询数据库,也可以将首次生成的csv_data存入session(注意控制数据大小不要超过session存储上限),在csv_download中直接读取session内容即可,避免重复查库消耗性能。
内容的提问来源于stack exchange,提问作者iamgda
相关产品推荐
相关产品推荐

