Наиболее распространенный подход к обмену данными между обратными вызовами - сохранить данные в объекте dash_core_components.Store
,
def serve_layout():
df = # Fetch data from DB
store = Store(id="mystore", data=df.to_json()) # The store must be added to the layout
return # Layout
Затем вы можете добавить хранилище в качестве аргумента State
для обратных вызовов, которые требуют доступ к данным,
@app.callback(..., [State("mystore", "data")])
def my_func(..., data):
df = pd.read_json(data)
Главный недостаток этого подхода - обмен данными между клиентом и сервером каждый раз, когда вызывается обратный вызов . Если фрейм данных мал, это не имеет особого значения, но если он большой, обмен данными (и сериализация в / из JSON) может вызвать серьезные проблемы с производительностью. Этого можно избежать путем кэширования серверной части фрейма данных либо вручную, как показано в документации , либо с использованием расширенных компонентов из dash-extensions
. Вот небольшой пример последнего,
import dash_core_components as dcc
import dash_html_components as html
import numpy as np
import pandas as pd
from dash_extensions.enrich import Dash, ServersideOutput, Output, Input, Trigger
app = Dash()
app.layout = html.Div([dcc.Store(id="store"), # this is the store that holds the data
html.Div(id="onload"), # this div is used to trigger the query_df function on page load
html.Div(id="log")])
@app.callback(ServersideOutput("store", "data"), Trigger("onload", "children"))
def query_df():
return pd.DataFrame(data=np.random.rand(int(10)), columns=["rnd"]) # some random example data
@app.callback(Output("log", "children"), Input("store", "data"))
def print_df(df):
return df.to_json() # do something with the data
if __name__ == '__main__':
app.run_server()
протестирован с dash-extensions==0.0.27rc1
. Отказ от ответственности: я являюсь автором dash-extensions
.