Reputation: 23
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
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