Flask 会话:文件系统的 OSError:[Errno 36] 文件名太长

问题描述

我有一个 Flask 应用程序,它接收一个用户/投资组合 ID 表单,然后创建一个页面来显示用户数据、信息、图表等。我正在尝试为每个用户插入一个下载 CSV 数据链接/按钮投资组合/工具。

我是通过烧瓶会议来做的。由于 CSV 数据超出了 cookie 限制,我需要使用特殊会话。到目前为止,我已经尝试使用 Redis 没有成功(但它可能是一个选项),所以我使用的是文件系统 Flask 会话,它给出了一个错误 OSError: [Errno 36] 文件名太长 em>.

这是我的代码的简化:

app.py

from flask import Flask,render_template,redirect,request,session,send_file
from flask_wtf import FlaskForm
from flask_session import Session #this module has upper and lower case versions - I'm using lower

from wtforms import StringField,SelectField,SubmitField,validators
from wtforms.validators import DataRequired

from flask_bootstrap import Bootstrap

#import my modules

app = Flask(__name__)

SESSION_TYPE = 'filesystem' #redis #filesystem
app.config.from_object(__name__)

Session(app)
Bootstrap(app)


app.config.from_mapping(SECRET_KEY=.....)


...

#home route
@app.route('/',methods=['GET','POST'])
def home():
     form = DataForm(request.form)
     if request.method == 'POST' and form.validate_on_submit():
         data_id = request.form['data_id']
         target= request.form['target']
    
         return redirect(f"/data/{target}/{data_id}")

return render_template('home.html',form=form)


#route which receives user/portfolio id,gets data and creates display page
@app.route('/data/<target>/<data_id>')
def customeranalysis(target,data_id):
    data_id = procedures.handle_id(data_id)

    if target == 'user':
        user_infos,user_names,graphs,annual_tables,twelve_months_tables,monthly_tables,csvs = procedures.user_info(data_id)
    
        for i in range(len(user_names)):
            session[user_names[i]] = csvs[i]
    
        return render_template('data_display_page.html',user_id=data_id,dfs=user_infos,names=user_names,graphs=graphs,annual_tables=annual_tables,twelve_months_tables=twelve_months_tables,monthly_tables=monthly_tables)
    if target == 'portfolio':
        #same as previous if,a little different


#route for the download page,to which the download link in previous route points
@app.route("/get_csv/<filename>",'POST'])
def get_csv(filename):
    df = session[filename]
    try:
        return send_file(df,as_attachment=True,attachment_filename='dados.csv'
                     )
    except FileNotFoundError:
        abort(404)


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

因此,在我的 data_display_page.html 模板页面中,我有以下代码,用于创建下载链接:

data_display_page.html

    {% for i in range(names| length) %}
    ...
        <a href="{{url_for('get_csv',filename=names[i])}}" id="download" class="btn btn-outline-info">Download data</a>
    ...

当我运行 docker-compose 时,一切运行良好,但是当我点击下载加载链接并被重定向时,我在浏览器和控制台上收到内部服务器错误,我得到以下信息:

cmd: docker-compose 错误

web_1  | 172.27.0.1 - - [15/Apr/2021 18:34:15] "GET /data/portfolio/portfolio_api_id HTTP/1.1" 200 -
web_1  | [2021-04-15 18:34:47,836] ERROR in app: Exception on /get_csv/portfolio_name[GET]
web_1  | Traceback (most recent call last):
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py",line 2447,in wsgi_app
web_1  |     response = self.full_dispatch_request()
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py",line 1952,in full_dispatch_request
web_1  |     rv = self.handle_user_exception(e)
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py",line 1821,in handle_user_exception
web_1  |     reraise(exc_type,exc_value,tb)
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/_compat.py",line 39,in reraise
web_1  |     raise value
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py",line 1950,in full_dispatch_request
web_1  |     rv = self.dispatch_request()
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py",line 1936,in dispatch_request
web_1  |     return self.view_functions[rule.endpoint](**req.view_args)
web_1  |   File "/code/app.py",line 86,in get_csv
web_1  |     return send_file(df,web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/helpers.py",line 629,in send_file
web_1  |     file = open(filename,"rb")
web_1  | OSError: [Errno 36] File name too long: #Long string which is actually not the CSV's name,but the CSV string itself

不知何故,它认为文件名是整个 CSV 字符串,包括所有列和行等。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...