Trey K
Trey K

Reputation: 23

DASH - get dataframe (df) outside function

I have a question about my code. The thing I’d like to accomplice is that I upload a *.db file and the file is put in a dataframe. After that I would like to do some things with the dataframe, but I cant get the df outside the function!

In the first Function (def parse_contents) the dataframe (df) is made with the query. If i put a print(df) in there i see that the df is filled with the info from the database file.

Then i return the df (return df) but i can’t the df outside the function! If I put a print(df) outside the function I get the error “NameError: name 'df' is not defined”

Is there somebody how can help to get the info from df in a other function? A global function doesn’t work with dash but cant find a solution for it.

Thanks

import dash_html_components as html
import dash_core_components as dcc
import dash
import sqlite3
import plotly
import dash_table as dte
from dash.dependencies import Input, Output, State
import pandas as pd



app = dash.Dash()

app.scripts.config.serve_locally = True
app.config['suppress_callback_exceptions'] = True

app.layout = html.Div([

    html.H5("Upload Files"),
    dcc.Upload(
        id='upload-data',
        children=html.Div([
            'Drag and Drop or ',
            html.A('Select Files')
        ]),
        style={
            'width': '100%',
            'height': '60px',
            'lineHeight': '60px',
            'borderWidth': '1px',
            'borderStyle': 'dashed',
            'borderRadius': '5px',
            'textAlign': 'center',
            'margin': '10px'
        },
        multiple=False),
    html.Br(),
    html.Button(
        id='propagate-button',
        n_clicks=0,
        children='Propagate Table Data'
    ),


    html.Br(),
    html.H5("Filter Column"),
    dcc.Dropdown(id='dropdown_table_filterColumn',
        multi = False,
        placeholder='Filter Column'),


    html.Br(),
    html.H5("Updated Table"),
    html.Div(dte.DataTable(data=[{}], id='table'))


])



def parse_contents(contents, filename):

    try:
        if 'db' in filename:

            conn = sqlite3.connect(filename)
            df = pd.read_sql('SELECT Date, Triage FROM Database', con=conn)
            print(df)
    except Exception as e:
        print(e)
        return None

    return df



@app.callback(Output('table', 'data'),
              [Input('upload-data', 'contents'),
               Input('upload-data', 'filename')])
def update_output(contents, filename):
    if contents is not None:
        df = parse_contents(contents, filename)
        if df is not None:
            return df.to_dict('records')
        else:
            return [{}]
    else:
        return [{}]






app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

if __name__ == '__main__':
    app.run_server(debug=True)

Upvotes: 2

Views: 550

Answers (1)

bas
bas

Reputation: 15722

I personally like using classes for this, but you could use dictionaries or other mutable data structures.

The basic idea is to initialize some type of mutable data structure with an initial value at a scope your functions have access to. Then at a later point in the app lifecycle we can mutate the data.

class DbResult:
    def __init__(self, data=None):
        self.data = data

    def store(self, data):
        self.data = data


db_result = DbResult() 

>>> db_result.data
None

# db_result.data is None here because data wasn't passed to the constructor
# and we gave data an initial value of None

This allows us to call db_result.store(data=df) inside the parse_contents function.

After this is set we can get the data in another function with db_result.data.

Upvotes: 1

Related Questions