Plotly Dash上传大体积文件无法展示数据表解决方案咨询
Dash大文件上传展示问题说明
问题复现代码
参考Plotly Dash官方文档编写的原生上传功能代码如下,用于实现上传csv/xlsx文件后展示对应数据表的功能:
import base64 import datetime import io from jupyter_dash import JupyterDash import dash from dash.dependencies import Input, Output, State from dash import dcc, html, dash_table import pandas as pd external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css'] app = JupyterDash(__name__, external_stylesheets=external_stylesheets) app.layout = html.Div([ dcc.Upload( id='upload-data', children=html.Div([ 'Drag and Drop or ', html.A('Select Files') ]), style={ 'width': '100%', 'height': '60px', 'lineHeight': '60px', 'borderWidth': '1px', 'borderStyle': 'dashed', 'borderRadius': '5px', 'textAlign': 'center', 'margin': '10px' }, # 允许多文件上传 multiple=True ), html.Div(id='output-data-upload'), ]) def parse_contents(contents, filename, date): content_type, content_string = contents.split(',') decoded = base64.b64decode(content_string) try: if 'csv' in filename: # 读取上传的CSV文件 df = pd.read_csv( io.StringIO(decoded.decode('utf-8'))) elif 'xls' in filename: # 读取上传的Excel文件 df = pd.read_excel(io.BytesIO(decoded)) except Exception as e: print(e) return html.Div([ 'There was an error processing this file.' ]) return html.Div([ html.H5(filename), html.H6(datetime.datetime.fromtimestamp(date)), dash_table.DataTable( df.to_dict('records'), [{'name': i, 'id': i} for i in df.columns], page_size =15 ), html.Hr(), # 水平分割线 # 调试用:展示浏览器返回的原始内容片段 html.Div('Raw Content'), html.Pre(contents[0:200] + '...', style={ 'whiteSpace': 'pre-wrap', 'wordBreak': 'break-all' }) ]) @app.callback(Output('output-data-upload', 'children'), Input('upload-data', 'contents'), State('upload-data', 'filename'), State('upload-data', 'last_modified')) def update_output(list_of_contents, list_of_names, list_of_dates): if list_of_contents is not None: children = [ parse_contents(c, n, d) for c, n, d in zip(list_of_contents, list_of_names, list_of_dates)] return children app.run_server(mode='external')
故障现象
- 体积在1MB-2MB区间的文件上传后可正常展示数据表
- 体积约14MB的文件无法正常完成展示
- 已尝试将
max_size属性设置为-1(即无文件大小限制),问题仍未解决
故障原因
原生dcc.Upload的实现逻辑是将文件在前端全量转为base64编码,再通过Dash回调传递到后端:
- base64编码本身会让文件体积膨胀约33%,14MB文件编码后大小接近19MB
- Dash回调默认对传递的payload大小有上限限制,同时大体积base64内容传递容易触发请求超时、前端内存占用过高导致页面无响应
- 仅修改
max_size参数无法绕过这个传输机制本身的性能瓶颈
解决方案
可以通过dash_uploader组件实现大文件上传后的数据表正常展示。该组件采用分片直传的模式,将文件直接写入服务端本地目录,不需要经过回调传递base64编码内容,从机制上避免了大文件传输的瓶颈。
配置步骤
- 安装组件:执行命令
pip install dash-uploader - 单独配置上传文件存储目录,不要将该目录放在
assets文件夹下,避免Dash自动扫描加载大文件拖慢应用响应 - 将原页面中的
dcc.Upload替换为dash_uploader提供的上传组件,配置允许的文件类型、单文件大小上限 - 回调逻辑改为直接读取服务端已保存的上传文件,解析后渲染数据表即可,不需要再处理base64解码逻辑
优化提示
渲染数据表时保留page_size分页参数配置,不要一次性把全量大表数据加载到前端,仅渲染当前页数据,避免前端渲染压力过大导致页面卡顿。
内容的提问来源于stack exchange,提问作者Sky_7
相关产品推荐
相关产品推荐

