3

I'm new to dash and I'm struggling to save the edits made on the dash data table back to a data frame here is my code of the data table

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

app = dash.Dash(__name__)


engine = sqlalchemy.create_engine('mysql+pymysql://root:@127.0.0.1:3306/sfp')

df = pd.read_sql_table("base_case",engine)

app.layout = html.Div([
    html.Div([
        dcc.Input(
            id='adding-rows-name',
            placeholder='Enter a column name...',
            value='',
            style={'padding': 10}
        ),
        html.Button('Add Column', id='adding-rows-button', n_clicks=0)
    ], style={'height': 50}),

    dash_table.DataTable(
        id='adding-rows-table',
        columns=[{"name": i, "id": i} for i in df.columns],
        data=df.to_dict('records'),
        editable=True,
        row_deletable=True
    ),

    html.Button('Add Row', id='editing-rows-button', n_clicks=0),
])

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

is there any solution to do that ?

Mehdi Selbi
  • 147
  • 2
  • 11

1 Answers1

3

You need a callback for it and this is an example how you could do it:

import dash
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

app = dash.Dash(__name__)

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/solar.csv')

nmb_clicks = 0
app.layout = html.Div([
    dcc.Store(id='click-memory', data = {'nmb_clicks': nmb_clicks}),
    html.Div([
        dcc.Input(
            id='adding-rows-name',
            placeholder='Enter a column name...',
            value='',
            style={'padding': 10}
        ),
        html.Button('Add Column', id='adding-columns-button', n_clicks=nmb_clicks)
    ], style={'height': 50}),

    dash_table.DataTable(
        id='adding-rows-table',
        columns=[{"name": i, "id": i} for i in df.columns],
        data=df.to_dict('records'),
        editable=True,
        row_deletable=True
    ),

    html.Button('Add Row', id='editing-rows-button', n_clicks=0),
])

@app.callback(dash.dependencies.Output('adding-rows-table', 'columns'),
             [dash.dependencies.Input('adding-columns-button', 'n_clicks'),
              dash.dependencies.Input('adding-rows-name', 'value')],
             [dash.dependencies.State('click-memory', 'data')])
def update_dropdown(click, name, data):
    if click != data['nmb_clicks']:
        if name not in df.columns:
            df[name] = [float('nan')] * len(df.index)

    return [{"name": i, "id": i} for i in df.columns]

@app.callback(dash.dependencies.Output('click-memory', 'data'),
             [dash.dependencies.Input('adding-columns-button', 'n_clicks')],
             [dash.dependencies.State('click-memory', 'data')])
def on_data(click, data):
    if click != nmb_clicks:
        data['nmb_clicks'] = data['nmb_clicks'] + 1

    return data

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

Note that you would need to fill the column with some meaningful values (now empty cell are being inserted).

Tony
  • 7,767
  • 2
  • 22
  • 51
  • i already achieved that i need to save the modified data in the editable table to a new dataframe – Mehdi Selbi Nov 20 '19 at 15:01
  • In your question you say "save back to dataframe" not "save to new dataframe". So you just need to save the copy of current dataframe to a new one? – Tony Nov 20 '19 at 15:15
  • You can just do `new_df = df[0:1]` in `update_dropdown` callback – Tony Nov 20 '19 at 15:28
  • 1
    A bit late but data from a DataTable is a list of dicts like [{col: value, col: value}, {col: value, col: value}] for a two column DataTable. Can you just do `df =pd.DataFrame(data)`? There's also this: https://community.plotly.com/t/callback-for-deleting-a-row-in-a-data-table/21437/4?u=nyck33 – mLstudent33 Nov 06 '20 at 05:04