每天更新一次分配给全局变量(外部回调)的数据

问题描述 投票:0回答:1

我正在创建一个使用大量数据的只读 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)

如果此代码中的全局数据每天更新,我如何在仪表板中更新它?

python plotly-dash
1个回答
0
投票

您尝试过使用日程包吗?您可以安排任务每天运行,如下所示:

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)

© www.soinside.com 2019 - 2024. All rights reserved.