Python 重新加载时以绘图方式刷新全局数据

Python 重新加载时以绘图方式刷新全局数据,python,pandas,plotly-dash,Python,Pandas,Plotly Dash,假设我有一个dash应用程序,我希望在页面重新加载时刷新全局数据。我正在使用一个函数为所描述的布局提供服务。但是,我确定应该如何/在何处定义df,以便在回调中使用它(例如,我希望根据一些输入将df子集并将其传递给布局表)。下面的代码在页面刷新时重新加载数据,但回调无法访问df 我对短跑非常陌生,所以提前为这个潜在的愚蠢问题道歉 def serve_layout(): df = # Fetch data from DB return # Layout app.layou

假设我有一个
dash
应用程序,我希望在页面重新加载时刷新全局数据。我正在使用一个函数为所描述的布局提供服务。但是,我确定应该如何/在何处定义
df
,以便在回调中使用它(例如,我希望根据一些输入将
df
子集并将其传递给布局表)。下面的代码在页面刷新时重新加载数据,但回调无法访问
df

我对短跑非常陌生,所以提前为这个潜在的愚蠢问题道歉

def serve_layout():
    df = # Fetch data from DB
    
    return # Layout

app.layout = serve_layout

@app.callback()
def my_func:
    # Here I want to reference df

在回调之间共享数据的最常见方法是将数据保存在
dash\u core\u组件中。存储
对象

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 
然后可以将存储添加为需要访问数据的回调的
状态
参数

@app.callback(..., [State("mystore", "data")])
def my_func(..., data):
    df = pd.read_json(data)
这种方法的主要缺点是,每次调用回调时,客户机和服务器之间都会交换数据。如果数据帧很小,这并不重要,但是如果数据帧很大,数据交换(以及JSON的序列化)可能会导致严重的性能问题。可以通过缓存数据帧服务器端来避免这种情况,如中所示,可以手动缓存,也可以使用
仪表板扩展
中的丰富组件。这是后者的一个小例子

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()

使用
仪表板延长件==0.0.27rc1进行测试。免责声明:我是
破折号扩展的作者

DB查询是否昂贵(即是否需要很长时间)?您是否有多个回调引用数据帧,还是只有一个回调?该查询可能很昂贵,并且将有多个回调引用数据。基本上,我希望能够按需重新提供全球数据集。但一旦数据加载,应用程序中的所有内容都将基于它。谢谢你的回答。如果数据帧很大,那么最好使用服务器端缓存还是将数据存储在浏览器中的隐藏div中?将数据存储在隐藏div中将产生与使用存储对象类似的性能。如果您的数据帧很大,服务器端缓存是一个不错的选择。这里可能有点偏离正轨,但您链接的文档中提到“请注意,文件系统缓存在具有像Heroku这样短暂文件系统的系统上不起作用。”。您知道这是否适用于GCP App Engine吗?我已经很久没有使用GCP App Engine了,但在部署到可扩展、无状态的云环境时,通常需要使用文件系统以外的另一种存储类型。不过这有点离题(也不是针对Dash),所以我认为应该在另一个问题上继续讨论。