Having trouble converting my dataframe into a list of dicts for DataTable

Upgraded all dependent packages. All works fine but still I’m getting error on

columns=[{“name”: i, “id”: i} for i in tab_df.columns],
AttributeError: ‘collections.OrderedDict’ object has no attribute ‘columns’

The table is loaded perfectly but I’m seeing this error for every request to callback.

Your tab_df is not a dataframe.

tab_df = pd.read_excel(‘C:\Users\N0207022\Desktop\NGRT\Config\HMR\{}.xlsx’.format(config), sheet_name=tab)

this should typically returns data frame. What am I doing wrong here?

@Philippe

this is producing ordered list but when I run the same statement in jupyter it is producing dataframe.

Can we see the whole app layout and callbacks related to tab_df ?

@app.callback(Output(‘tab_data’, ‘children’),
[Input(‘config_list’, ‘value’),
Input(‘sheet_names’, ‘value’)]
)
def display_tab_data(config, tab):

tab_df = pd.read_excel(‘C:\Users\N0207022\Desktop\NGRT\Config\HMR\{}.xlsx’.format(config), sheet_name=tab)

table_data = dash_table.DataTable(
id=‘table’,
columns=[{“name”: i, “id”: i} for i in tab_df.columns],
data=tab_df.to_dict(“rows”),
n_fixed_rows=1,
style_table={‘overflowX’: ‘scroll’,
‘maxHeight’: ‘700px’,
‘maxWidth’: ‘1500px’,
‘border’: ‘thin lightgrey solid’
},
style_cell={‘width’: ‘150px’,
‘textAlign’: ‘left’
},
style_cell_conditional=[
{
‘if’: {‘row_index’: ‘odd’},
‘backgroundColor’: ‘rgb(248, 248, 248)’
}
],
style_header={
‘backgroundColor’: ‘#3DC2ED’,
‘fontWeight’: ‘bold’
},
css=[{
‘selector’: ‘.dash-cell div.dash-cell-value’,
‘rule’: ‘display: inline; white-space: inherit; overflow: inherit; text-overflow: inherit;’
}],

)

return table_data

Time to read the documentation: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_excel.html !

Particularly let’s look at the resturn value:

parsed : DataFrame or Dict of DataFrames

DataFrame from the passed in Excel file. See notes in sheet_name argument for more information on when a Dict of Dataframes is returned.

Aha, so sometimes we get a dictionary instead of a DataFrame, let’s look at sheet_name to see why:

sheet_name : string, int, mixed list of strings/ints, or None, default 0
Strings are used for sheet names, Integers are used in zero-indexed sheet positions.

Lists of strings/integers are used to request multiple sheets.

Specify None to get all sheets.

str|int -> DataFrame is returned. list|None -> Dict of DataFrames is returned, with keys representing sheets.

Available Cases

  • Defaults to 0 -> 1st sheet as a DataFrame
  • 1 -> 2nd sheet as a DataFrame
  • “Sheet1” -> 1st sheet as a DataFrame
  • [0,1,”Sheet5”] -> 1st, 2nd & 5th sheet as a dictionary of DataFrames
  • None -> All sheets as a dictionary of DataFrames

So it seems like your variable “tab” is either a list or None. Either are possible from the code, you’ve not given us the layout so we can’t tell. Print out the variable “tab” and you should be able take it from there!

2 Likes

Ok. Thats the problem. While loading the app, tab is None. So, I’m going to validate the tab before read_excel. I didn’t realize this. Thanks for pointing out.

Nice work showing how to dig through the documentation @Damian :heart: