Flask集成Dash实时K线图不更新,Binance WebSocket入库正常如何解决
问题根因与解决方案
两个核心错误导致图表无法实时更新:
- 回调触发条件拼写错误:
dcc.Interval组件的计数属性为n_intervals,你的代码回调参数中写为n_interval,少了末尾的s,导致定时回调完全不会被触发 - 数据读取逻辑错误:
rec = pd.read_sql_table('crypto', engine)写在全局作用域,只会在应用启动时执行一次,后续所有回调都使用启动时缓存的旧数据,不会拉取数据库最新内容
修复后可运行代码
注意保留你原有代码中数据库engine的初始化逻辑:
import plotly import dash from dash.dependencies import Output, Input from dash import dcc from dash import html import pandas as pd import plotly.graph_objs as go import flask import waitress from waitress import serve # 保留你原有代码中engine的初始化代码,不要删除 # engine = 你的数据库连接初始化逻辑 server = flask.Flask(__name__) app = dash.Dash(__name__, server=server) app.layout = html.Div( html.Div([ dcc.Graph(id='live-update-graph-scatter', animate=True), dcc.Interval( id='interval-component', disabled=False, interval=1*1000, n_intervals=0 ) ]) ) # 修正回调参数拼写,每次回调重新读取数据库最新数据 @app.callback(Output('live-update-graph-scatter', 'figure'), [Input('interval-component', 'n_intervals')]) def update_graph_scatter(n): def updatesql(): # 每次回调都重新从数据库拉取最新数据 rec = pd.read_sql_table('crypto', engine) rec1 = pd.DataFrame(rec) rec1.columns = ['date', 'open', 'high', 'low', 'close', 'volume'] rec1['date'] = pd.to_datetime(rec1['date']) rec1.set_index('date', inplace=True) return rec1 rec1 = updatesql() data = plotly.graph_objects.Candlestick( x=rec1.index, open=rec1['open'], high=rec1['high'], low=rec1['low'], close=rec1['close']) return {'data': [data], 'layout' : go.Layout(xaxis=dict(range=[min(rec1.index), max(rec1.index)], linecolor='white', linewidth=2, gridcolor='white' ), yaxis=go.YAxis(dict(range=[min(rec1.low) - 5, max(rec1.high) + 5], linecolor='white', linewidth=2, gridcolor='white' ) ), title='BNB Price', plot_bgcolor='white', paper_bgcolor='white', font={'color': 'black'}, legend={'orientation': "h", 'x': .1, 'y': -.2} ) } if __name__ == '__main__': serve(app.server, host="localhost", port=8080)
可选优化建议
- 避免全表扫描:如果数据库存储的历史数据越来越多,每次全表读取会拖慢更新速度,可以加时间过滤条件只拉取最近需要展示的K线数据
- 增加异常捕获:给数据库读取逻辑加异常捕获,避免数据库连接中断、空数据等问题导致服务崩溃
- 调整更新频率:如果不需要秒级更新,可适当把Interval的interval从1000ms调整到2000-3000ms,降低数据库和服务压力
内容的提问来源于stack exchange,提问作者Mathias Albrechtsen
相关产品推荐
相关产品推荐

