Store dataframe and share between multipages

Hello All,

I have a multi pages dash app, on which I read multi dataframe. Some pages use the same dataframe.

I want to know how store all dataframe and how share, access it from other pages.

My app tree is:

myapp

  • app.py
  • sidebar.py
  • pages
    • first_page
    • second_page

etc

The idea is open all dataframe from db in app.py or other and in pages use the store.

I read a lot of different solution, but they use all a button to read the data and I don 't want.

app.py:

from dash import Dash
from sidebar import serve_layout

app = Dash(name, use_pages=True)

server = app.server

app.layout = serve_layout

if name == ‘main’:
app.run_server(host=‘0.0.0.0’, port=‘8888’, debug=True)

sidebar.py:

def serve_layout():
layout = dbc.Container([
dbc.Row([
dbc.Col([offcanvas], class_name=“col-menu”),
],class_name=“row-menu”),
dbc.Row([
dbc.Col([dash.page_container])
]),
], class_name=“dbc”)

return layout

and a random page:

import dash
from dash import callback, Input, Output
from dash import html, dcc, dash_table
import pandas as pd
import dash_bootstrap_components as dbc
from get_rawdata_db.get_rawdata_db import read_from_db
import configparser

try:
config = configparser.ConfigParser()
config.read(‘settings.ini’)
except Exception as e:
print(e)

host = config[‘db’][‘host’]
db = config[‘db’][‘db’]
usr = config[‘db’][‘usr’] if config[‘db’][‘usr’] else os.getenv(‘TUXPRDSQL_DB_USR’)
psw = config[‘db’][‘psw’] if config[‘db’][‘psw’] else os.getenv(‘TUXPRDSQL_DB_PSW’)
table = config[‘db’][‘table’]

dash.register_page(name, path=‘/report’, order=0)

title = html.Div(html.H4(“Report”),className=“title-menu”)

report = read_from_db(host, db, usr, psw, table)

table = html.Div([
#dcc.Interval(‘refresh’, interval = 30000, n_intervals = 0),
dash_table.DataTable(
id=‘table-home’,
columns=[{“name”: i, “id”: i, “hideable”: True} for i in report.columns],
data=report.to_dict(‘records’),
sort_action=‘native’,
sort_mode=“multi”,
hidden_columns=[‘fqdn’, ‘product_name’,‘cms_product_id’, ‘ip’, ‘powerstate’],
filter_action=‘native’,
filter_options={‘case’:‘insensitive’},
page_action=“native”,
page_size= 30,
export_format=“xlsx”,
#virtualization=True,
#style_table={‘minWidth’: ‘100%’},
#fixed_columns={‘headers’: True, ‘data’: 2},
)],className=“dbc dbc-row-selectable”)

layout = html.Div([
dbc.Row(title),
dbc.Row(table)])

@callback(
dash.dependencies.Output(‘table-home’,‘data’),
[dash.dependencies.Input(‘refresh’, ‘n_intervals’)])

def updateTable(n):
report = read_from_db(host, db, usr, psw, table)

return report.to_dict('records')

Someone can help me ?

HI @nmy, welcome to the forums.

You could directly “fill” the store when defining it:

dcc.Store(id='store_1', data= your_JSNON_df

you could also initiate the app with an empty store, run your data acquisition process and let this process update the store(s)

Note tha in the following, the dummy is just for triggering the callback at startup as I do not prevent the initial call.
prevent_initial_call=False (which is default)


app.layout = html.Div([
    dcc.Store(id='1'),
    dcc.Store(id='2'),
    dcc.Store(id='3'),
    html.Div(id='dummy')
])


@app.callback(
    Output('1', 'data'),
    Output('2', 'data'),
    Output('3', 'data'),
    Input('dummy', 'style')
)
def update(_):
    return your_JSNON_df_1, your_JSNON_df_2, your_JSNON_df_3

Hello,

well if I understood , I need to put this:

app.layout = html.Div([
dcc.Store(id=‘1’),
dcc.Store(id=‘2’),
dcc.Store(id=‘3’),
html.Div(id=‘dummy’)

into sidebar.py

like this:

def serve_layout():
layout = dbc.Container([
dcc.Store(id=‘report’),
dcc.Store(id=‘history_report’),
html.Div(id=‘dummy’),
dbc.Row([
dbc.Col([offcanvas], class_name=“col-menu”),
],class_name=“row-menu”),
dbc.Row([
dbc.Col([dash.page_container])
]),
], class_name=“dbc”)

return layout

@callback(
Output(‘report’, ‘data’),
Output(‘history_report’, ‘data’),
Input(‘dummy’, ‘style’)
)
def update(_):
report = pd.read_csv(‘data/cmsreport.csv’)
report.to_json(report)
history_report = pd.read_csv(‘data/history_report.csv’)
history_report.to_json(history_report)

return report, history_report

])

and in pages/report how can I use it ?

HI, you can retrieve the data in a callback

@app.callback(
    Output(),
    Input(),
    State(id='report', 'data')
)
def update(arg, data):
    process data
    return processed data

see also:

@adamschroeder has a video about this also:

so we need an Input ?

I do this:

myapp/pages/report.py:

layout = html.Div([
dbc.Row(title),
dbc.Row(id=“table-output”)])

@callback(
Output(‘table-output’, ‘children’),
Input(‘report’, ‘data’))

def update_table():

report = pd.read_json(report, orient='split')
    
table = html.Div([
    #dcc.Interval('refresh', interval = 30000, n_intervals = 0),
    dash_table.DataTable(
        id='table-home',
      columns=[{"name": i, "id": i, "hideable": True} for i in report.columns], 
        data=report.to_dict('records'),
      sort_action='native', 
      sort_mode="multi",
      hidden_columns=['fqdn', 'product_name','cms_product_id', 'ip', 'powerstate'],
      filter_action='native',
      filter_options={'case':'insensitive'},
      page_action="native",
        page_size= 30,
      export_format="xlsx", 
        #virtualization=True,
        #style_table={'minWidth': '100%'},
        #fixed_columns={'headers': True, 'data': 2},
    )],className="dbc dbc-row-selectable")

return table

and in myapp/sidebar.py:


report = pd.read_csv(‘data/cmsreport.csv’)

report = report.to_json(orient = ‘records’)

def serve_layout():
layout = dbc.Container([
dcc.Store(id=‘report’, data=report),
dbc.Row([
dbc.Col([offcanvas], class_name=“col-menu”),
],class_name=“row-menu”),
dbc.Row([
dbc.Col([dash.page_container])
]),
], class_name=“dbc”)

return layout

but on the page report I have a black screen :confused:

Most likely the callback doesn’t get triggered because you initiate your dcc.Store() with the data. Input() “detects” a change in the corresponding component/property but since the data is not changing…
But on the other hand you are not preventing the initial call so I’m not 100% sure.

Try returning html.Div('test') instead of table just to see, if the callback gets triggered.

HI @nmy
:wave: Welcome to the community.

To make it easier to read and copy your code, don’t forget to put it in preformatted text.