`row_update` in `dash_table.DataTable`

Hello,

I started using the new package dash_table instead of dash_table_experiments, and I would like know what is the equivalent of ‘row_update’ property for dash_table. Thanks :slight_smile:

Hi anniyan, this documentation https://dash.plot.ly/datatable/editable mentions how to determine which row/column has changed.

1 Like

In dash-table-experiments, we could update the rows from a callback by using

@app.callback(Output('datatable', 'rows'),

Once that is done, the dash table would infer the columns automatically.

In this new version, it does not (or maybe I am doing something wrong).

Is there a way to update the rows and columns together? or maybe even other properties
of the dash-table? Like how we do it with a figure as shown below?

@app.callback(
    Output('awesome-fig', 'figure'),
    [Input('ABC', 'value'),
     Input('DEF', 'value'),

and then we do a return type like this

return {
        'data': traces,
        'layout': go.Layout(
            title='Some Awesome graph',
            xaxis=dict(
                showticklabels=True,
                dtick=1,
            ),
            yaxis=dict(
                dtick=1,
            ),
            
        )
    }

So for a table can I do a return statement as shown below?

return {
        'data': data.to_dict("rows"),
        'columns': [{"name": i, "id": i} for i in data.columns],
    }

In that case what is the callback output?

@app.callback
    (Output('datatable', 'WHATWOULDTHISBE?'),

For now, you would need to do two separate callbacks, one that updates Output('datatable', 'data'), and the next that updates Output('datatable', 'columns'). This will become much simpler once we have support for multiple outputs (in progress)

Thanks for the clarification. multiple outputs would be awesome, that would solve many of the limitations of Plotly.

Keep up the good work.

2 Likes

I used ‘active_cell’ with ‘data_timestamp’. I also used that to make a call back to update a database table.

import time
import pandas as pd
import dash_table
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html


app = dash.Dash()
app.config.suppress_callback_exceptions = False
app.scripts.config.serve_locally = True
app.css.config.serve_locally = True

df = pd.DataFrame([[1, 2], [3, 4], [5, 6], [7, 8]], columns=["A", "B"])
           
app.layout = html.Div([
    html.H1(
        children='Sample Table - Shows how to identify modified Row',
        style={
            'textAlign': 'center'
        }
    ),

                   
    dash_table.DataTable(
                id='table-editing-simple',
                columns=[
                    {"name": "A", "id": "A", "editable": False},
                    {"name": "B", "id": "B", "editable": True}],
                data = df.to_dict("rows"),
                editable = True
                ),
    html.Div(
            html.H5(
                id='table-action-outputs',
                children='',
                style={'textAlign': 'left'}),
            style={'width': '100%', 'display': 'inline-block', 'float': 'left'},
            ),

])



@app.callback(Output('table-action-outputs', 'children'),
              [Input('table-editing-simple', 'data_timestamp'),
              Input('table-editing-simple', 'active_cell'),
              Input('table-editing-simple', 'data')])
def update_database(time_updated, cell_coordinates, table_data):
    time_updated = round(time_updated / 1000)
    time_now = round(time.time()) - 2
    if (time_updated) >= time_now:
       db_response = str(time_updated) + " " +  str(time_now)
       str_return = "Data timestamp:" + str(time_updated) 
       str_return2 = ".  Did you update this row? " + str(table_data[cell_coordinates[0]])
       sql_query = "UPDATE table SET B = '{table_data[cell_coordinates[0]][cell_coordinates[1]]}', MODIFIED_DATE = {time_updated} WHERE A = '{table_data[cell_coordinates[0]][cell_coordinates[0]]}'"
       db_response = f".  Sample DB SQL Update statement: {sql_query}"  
    else:
       time_round = round(time.time())
       str_return = "No time match. " + str(type(time_updated)) + " is the Dash updated time which does not match this server time:  " + str(time_round) + "\n"
       str_return2 = ".  No matching record found due to time issue.\n"
       db_response = ".  No DB update due to time gap issue.\n"
    return str_return, str_return2, db_response

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

1 Like

@fish_in_mn why did you have the conditional for if time_updated >= time_now?

also, can you walk me through how you sent the updated row to a database table? can you include some code snippets of how you structured the query?

@ShreyasT - I didn’t want to make an update call to the database every time a cell or row was selected. So, I added that time check. Without the time_updated >= time_now it would update the row in my backend DB every time a row was selected.

1 Like

sql_query = “UPDATE table SET B = ‘{table_data[cell_coordinates[0]][cell_coordinates[1]]}’, MODIFIED_DATE = {time_updated} WHERE A = ‘{table_data[cell_coordinates[0]][cell_coordinates[0]]}’”

I would make the above line a f string. Ex. sql_query = f"UPDATE…"

Then use that in a in a call to a DB such as the one illustrated here: https://www.w3schools.com/python/python_mysql_update.asp

1 Like

Thank you so much man! Kudos!

@fish_in_mn So with the code you provided for time_updated and time_now, you’re updating the DB every 2 seconds?