Hello, I am writing a CRUD application that allows the user to fill out information and submit it to the database. In my Submit callback I am getting consistent stack overflow errors when the callback is triggered. I think it may have something to do with using a large amount of dictionaries in one callback but I have no clue how to troubleshoot and mitigate this. I am using Python version 3.7 and Dash version 2.11.1. My callback is below. If someone could help me troubleshoot this issue it would be greatly appreciated.
#Submit Callback
@app.callback(
Output('hidden-div','children'),
Input('submit', 'n_clicks'),
State('browse-path', 'value'),
State({'group': ALL, 'type': 'input','index': ALL},'id'), #All input IDs (15 Total)
State({'group': ALL, 'type': 'input','index': ALL},'value'), #All input Values (15 Total)
State({'group': ALL, 'type': 'drop','index': ALL},'id'), #All dropdown IDs (14 Total)
State({'group': ALL, 'type': 'drop','index': ALL},'value'), #All dropdown IDs (14 Total-- can contain a list of values)
State({'type':'textarea', 'index':ALL},'id'), #All text area IDs (4 total)
State({'type':'textarea', 'index':ALL},'value'), #All text area values (4 total)
State('Date', 'date'), #Date from singledate picker
State({'group': 'tbl1','type': 'tbl', 'index': 'Table 1'}, 'data'), #Table 1 data (editable but can contain a max of 8 rows, 6 columns)
State({'group': 'tbl2','type': 'tbl', 'index': 'Table 2'}, 'data'), #Table 2 data (editable but can contain a max of 6 rows, 6 columns)
State('folder-switch', 'value'), #A switch.. can only contain a binary value
prevent_initial_call=True
)
def submit(n_clicks, folder, iid, ival, ddid, ddval, textareaid,textareaval,
date,tbl1,tbl2,switch):
#zip inputs and dropdowns
datainputs = {item['index']: value for item, value in zip(iid, ival)}
ddinputs = {item['index']: value for item, value in zip(ddid, ddval)}
textarea= {item['index']: value for item, value in zip(textareaid, textareaval)}
#Create Test Table
testtbl= {
'Test_ID':datainputs['Test #'],
'Test_Title':datainputs['Test Title'],
'Test_Date':date,
'Test_Type':ddinputs['Test Type'],
'Test_Summary':textarea['Test Summary'],
'Anomalies_Observed':textarea['Anomalies Observed'],
'Other_Observations':textarea['Other Observations'],
'Test_Limitations':textarea['Test Limitations'],
'Test_Folder':folder,
'Analysis_Status':ddinputs['Analysis Status'],
'Lead_Analyst':ddinputs['Lead Analyst'],
'Date_Entered':now.strftime('%Y-%m-%d %H:%M:%S'),
'Date_Edited':now.strftime('%Y-%m-%d %H:%M:%S'),
'Test_Edited':now.strftime('%Y-%m-%d %H:%M:%S')}
testtbl= pd.DataFrame(testtbl, index=[0])
#Create Table 1 Table
#Function to convert list of dictionaries to one dictionary
def merge_list_of_dicts(list_of_dicts):
merged_dict = defaultdict(list)
for dictionary in list_of_dicts:
for key, value in dictionary.items():
merged_dict[key].append(value)
return dict(merged_dict)
# tbl1= merge_list_of_dicts(tbl1)
# tbl1.update({
# 'Test_ID':testtbl['Test_ID'],
# 'Date_Entered':now.strftime('%Y-%m-%d %H:%M:%S'),
# 'Date_Edited':now.strftime('%Y-%m-%d %H:%M:%S'),
# })
#tbl1= pd.DataFrame(tbl1, index=[0])
#The 'cleandf' function changes empty white space and NONE data type items in a dataframe to 'NA'
#It also strips white space from the beginning and start of strings in a dataframe
def cleandf(df):
mask = ((df.applymap(type) == str) & (df.applymap(lambda x: str(x).strip() == ''))| df.applymap(pd.isnull))
df=df.where(~mask, other='NA')
df=df.apply(lambda x: x.str.strip().str.replace(r'(?i)^n/a$', 'NA', regex=True) if x.dtype == "object" else x) #r'(?i)^n/a$' is a regular expression that captures all variations of 'n/a'
df = df.apply(lambda x: x.str.strip() if x.dtype == "object" else x)
return df
testtbl= cleandf(testtbl)
#Check for valid Test ID and Title
if testtbl['Test_ID'][0]=='NA':
print('Bad Test #')
return None
if testtbl['Test_Title'][0]=='NA':
print('Bad Test Title')
return None
#Check Table 1
#Updates Sqlite3 Database
conn = sqlite3.connect(db_file)
try:
testtbl.to_sql('Test', conn, if_exists='append', index=False)
print('Test Table Updated succesfully')
conn.close()
except sqlite3.Error as e:
print(f"SQLite3 Error: {e}")
conn.close()
return None
#Create folders
directory= 'Test'
path = os.path.join(folder, directory)
try:
os.makedirs(path, exist_ok = True)
print("Directory '%s' created successfully" % directory)
except OSError as error:
print(str(error))
return None