Dash / Plotly / Python обновляет редактируемую таблицу по ячейке, введите или щелкните и добавьте новую строку в таблицу данных по нажатию кнопки - PullRequest
0 голосов
/ 17 января 2019

Я работаю с Dash / Python и имею DataTable (эксперименты), который заполняется из базы данных. То, что я хочу сделать, - это когда я начинаю набирать в любой ячейке таблицы для обновления в базе данных и когда я нажимаю «Добавить новую строку», добавляется новая пустая строка с последним индексным номером. Теперь обновление таблицы и вставка строки работают должным образом отдельно, но я не могу различить нажатие на кнопку и нажатие внутри таблицы. Я пытаюсь сделать это внутри цикла if-else в Python, но этот код не работает. Я не могу поймать правильно, когда нажата кнопка, if n_clicks не работает, и обновление базы данных внутри всегда вызывается, независимо от того, добавляю я новую строку или нет.

Это код, отвечающий за добавление новой строки (которая вставляется в базу данных) и обновление ячейки таблицы (которая обновляет базу данных). Каждый раз, когда я нажимаю кнопку «Добавить строку», запускается также обновление «если», которое я не хочу. Нажатие на кнопку «Добавить новую строку» должно выполнять только «elif» часть кода, но для этого мне нужно различать клики. То, что у меня сейчас есть, не делает этого. Я попытался извлечь добавление новой строки в новую функцию, но для этого мне нужно иметь одинаковые выходные данные («my-datatable», «lines»), и Dash не поддерживает его. Есть ли другой способ сделать это? Я использую данные таблицы экспериментов.

import dash_table_experiments as dt
from dash.dependencies import Input, Output, State

app.layout = html.Div(children=[
    dt.DataTable(
        id='my-table',
        rows=df.sort_values('id').to_dict('records'),
        editable=True,
        row_update=True,
        filterable=True,
        sortable=True,
        row_selectable=True
    ),
    html.Button('Add Row', id='add-row-button', n_clicks=0)])

@app.callback(
Output('my-table', 'rows'),
[Input('my-table', 'row_update'),
Input('add-row-button', 'n_clicks')],
[State('my-table', 'rows')])
def update_rows(row_update, n_clicks, rows):
    if (type(row_update) != bool):
        value = list(row_update[0]['updated'].values())[0]
        column = list(row_update[0]['updated'].keys())[0]
        row_index = row_update[0]['from_row']

        query=f"""BEGIN
            UPDATE my_table
            SET  {column}='{value}'
            WHERE id={row_index + 1}
          END;"""

        cursor.execute(query)
        connection.commit()

        get_query = "SELECT * FROM my-table ORDER BY id"
        rows = pd.read_sql(get_query, connection)
        rows = rows.sort_values('id').to_dict('records')

    # else if 'add new row' button has been clicked, 
    # insert a new empty row in a database which will show as a new row 
    # with index number on a DataTable and treat it as an update later

    elif n_clicks:
        query_insert = f"""BEGIN
                      INSERT INTO my-table
                      DEFAULT VALUES
                   END;"""

        cursor.execute(query_insert)
        connection.commit()

        get_query = "SELECT * FROM my-table ORDER BY id"
        rows = pd.read_sql(get_query, connection)
        rows = rows.sort_values('id').to_dict('records')

    return rows
...