通过按钮点击与Interval双回调更新Dash DataTable的异常问题排查
问题根因
- Dash 框架存在硬性约束:同一个组件的同一个属性,不能被多个回调函数同时作为输出目标。你的代码中
updateTable和addRow两个回调都绑定了Output('table','data'),运行时会触发回调冲突,导致两个逻辑都无法正常生效。 - 额外提示:示例中用
global全局变量存储表格数据仅适合单用户测试场景,多用户访问时会出现全局数据被篡改的问题,生产环境建议改用dcc.Store组件存储状态。
修复方案
将两个触发源合并到同一个回调中,通过callback_context判断当前触发回调的组件,分别执行新增行、定时更新行的逻辑即可。完整可运行的修改后代码如下:
import dash_core_components as dcc import dash_html_components as html from dash import callback_context import dash_table import pandas as pd import numpy as np import dash_bootstrap_components as dbc app = dash.Dash(__name__) tblcols=[{"label": "id", "id": "id"}, {"label": "x", "id": "x"}, {"label": "y", "id": "y"}] df_table = pd.DataFrame([{'id': 'id_0', 'x': 0, 'y': 0}], columns=[col['label'] for col in tblcols]) def getData(id): n = np.random.random(1)[0] return {'id':f'id_{id}', 'x': n, 'y': n} app.layout = html.Div([ html.H4('Dashboard'), html.Button('Add Row', id='add-btn', n_clicks=0), dcc.Interval('table-update', interval=1_000, n_intervals = 0), dash_table.DataTable( id='table', data= df_table.to_dict('records'), columns=tblcols ) ]) # 合并后的单回调,同时监听两个输入源 @app.callback( dash.dependencies.Output('table','data'), [dash.dependencies.Input('table-update', 'n_intervals'), dash.dependencies.Input('add-btn', 'n_clicks')] ) def handle_table_update(n_interval, n_clicks): global df_table # 判断触发回调的组件 trigger_id = callback_context.triggered[0]['prop_id'].split('.')[0] # 点击新增行逻辑 if trigger_id == 'add-btn': df_table = pd.concat([df_table, pd.DataFrame([getData(len(df_table))])], ignore_index=True) # 定时更新行数据逻辑 elif trigger_id == 'table-update': for id in range(len(df_table)): n = np.random.random(1)[0] df_table.loc[df_table['id'] == f'id_{id}', ['x', 'y']] = [n, n + 6] return df_table.to_dict('records') if __name__ == '__main__': app.run_server(debug=False)
内容的提问来源于stack exchange,提问作者knn7713
相关产品推荐
相关产品推荐

