DataTable callback update of 'columns' argument causes blank table


I’ve been enjoying creating my first Dash app the last couple of days. It’s been a great experience and so far I’ve found I can do everything I want to relatively easily.

I’ve just tried adding a DataTable element to the app and have run into some confusing behaviour. I was able to add the DataTable successfully by using the following:

    style={'width': '60%', 'display': 'inline-block'})


    Output('conc-table', 'data'),
    Input('metabolite-selection', 'value'),
    Input('conc-selection', 'value'))
def update_conc_table_data(metabolites, field):
    df = df.loc[metabolites, field].unstack('Metabolite').describe()
    return df.reset_index().to_dict('records')

This displays the table and allows me to add more columns to this table if the metabolites list is extended by the metabolite-selection dropdown element. So far so good.

I then wanted to format the numerical data in this table to have a fixed precision. So I added the following callback:

    Output('conc-table', 'columns'),
    Input('metabolite-selection', 'value'))
def update_conc_table_columns(metabolites):
    col_format = [dict(id='conc-table_index', name='index', type='text'), ]\
        + [dict(id=f'conc-table_{idx}',
                format=Format(precision=3)) for idx in range(len(metabolites))]
    return col_format

But this results in a blank table except for the column names which are defined in col_format. The table is the right shape (number of rows and columns), but all the data fields are empty.
col_format has this value [{'id': 'conc-table_index', 'name': 'index', 'type': 'text'}, {'id': 'conc-table_0', 'name': 'NAA', 'type': 'numeric', 'format': <dash.dash_table.Format.Format object at 0x7ff1ff3cb430>}]

Any ideas on what I’m doing wrong? Am I taking the wrong approach to have a dynamically sized table with a defined numerical precision?

Thanks in advance for any help.