我正在创建一个使用大量数据的只读 Plotly Dash 仪表板。它涉及大量的数据库读取和转换,通常需要长达 1 分钟的时间。为了避免用户在每次交互时等待这么长时间,我在回调之外执行这些步骤并将数据分配给全局变量。这些步骤仅在第一个用户打开仪表板时执行一次。
仪表板有过滤器。当用户更改过滤器时,我根据回调函数中选定的过滤器过滤全局数据(在不同的变量中)并显示数据。由于数据已经在服务器上可用,因此后续交互速度很快。全局数据不会从回调中更新。这个工作很棒并且表现良好。
我使用的数据具有每日粒度。我需要每天更新一次这个全局数据,以确保全局数据是最新的。如何更新此全局数据?我想我可以使用 Redis 作为中间存储,每天更新一次,所有回调都从 Redis 读取,但这可以在没有中间层的情况下完成吗?
这是示例代码:
from dash import Dash, dcc, html, Input, Output, callback
import pandas as pd
from dash_ag_grid import AgGrid
def get_global_data():
data_df = pd.DataFrame()
# Lot of DB reads and transformations
return data_df
global_data = get_global_data()
app = Dash(__name__)
app.layout = html.Div([
html.H6("Select country to view data!"),
dcc.Dropdown(['USA', 'Canada', 'Mexico'], 'USA', id='country-dropdown'),
html.Br(),
AgGrid(
id="data-grid",
defaultColDef={"resizable": True, "sortable": True, "filter": True},
columnSize="sizeToFit",
style={'width': '100%'},
)
])
@callback(
Output('data-grid', 'rowData'),
Output('data-grid', 'columnDefs'),
Input(component_id='country-dropdown', component_property='value')
)
def update_table(input_country):
filtered_data = global_data[global_data['country']==input_country]
filtered_data_as_dict = convert_df_to_dict(filtered_data) # convert to dict
column_defs = create_column_def(filtered_data) # generates column def
return filtered_data_as_dict, column_defs
if __name__ == '__main__':
app.run(debug=True)
如果此代码中的全局数据每天更新,我如何在仪表板中更新它?
您尝试过使用日程包吗?您可以安排任务每天运行,如下所示:
import schedule
import time
import pandas as pd
def get_global_data():
data_df = pd.DataFrame()
# Lot of DB reads and transformations
return data_df
def update_global_data():
global global_data
global_data = get_global_data()
# Initialize global_data
global_data = get_global_data()
# Schedule the update function to run daily
schedule.every(1).day.at("00:00").do(update_global_data)
if __name__ == '__main__':
while True:
schedule.run_pending()
time.sleep(1)