问题描述
我正在尝试构建一个破折号应用程序,它接受用户的输入并将每个条目附加到数据框中,但它正在替换旧条目并生成一个新条目.我不确定回调中有什么问题.还尝试构建一个逻辑,如果用户条目与数据框的任何行匹配,那么它只会替换 else append.
I am trying to build a dash app which takes input from users and append each entry in the data frame, but it's replacing the old entry and generating a new one. I am not sure what's wrong in the callback.also trying to build a logic if the user entry matches with any row of data frame then only it will replace else append.
非常感谢您的帮助:
@app.callback(Output('save-query', 'children'),
[Input('save', 'n_clicks')],
[State('ad_account_id', 'value'),
State('app_id', 'value'),
State('access_token', 'value'),
State('app_secret', 'value'),
State('metrics', 'value'),
State('breakdown', 'value'),
State('start-date', 'date'),
State('end-date', 'date'),
State('save-as', 'value')
],
)
def save_query(clicks, ad_account_id, app_id, access_token, app_secret, metrics, breakdown,
start_date, end_date, save):
if clicks is not None:
my_ad_account = ad_account_id
my_app_id = app_id
my_access_token = access_token
my_app_secret = app_secret
my_metrics = metrics
my_breakdown = breakdown
my_start_date = start_date
my_end_date = end_date
my_save = str.lower(save)
data = [[my_save, my_ad_account, my_app_id, my_access_token, my_app_secret, my_metrics, my_breakdown,
my_start_date,
my_end_date]]
df = pd.DataFrame(data, columns=['report_name', 'ad_account', 'app_id', 'access_token',
'app_secret', 'metrics', 'breakdown',
'start_date', 'end_date'])
dff = df.append(df)
return html.Div([
dash_table.DataTable(
css=[{'selector': '.row',
'rule': 'margin: 0; white-space: inherit; overflow: inherit; text-overflow: inherit;'}],
id='table',
columns=[{"name": i, "id": i} for i in dff.columns],
data=dff.to_dict("rows"), )],
style={'margin-top': 30, 'display': 'inline-block', 'margin-left': 20, 'width': '100%'})
推荐答案
由于全局变量的变异是 在 Dash 中不鼓励,启用对当前数据的访问的标准方法是添加一个将数据保存为 State
参数的组件.它可以是一个单独的组件(例如一个 Store
组件)或仅仅是数据表本身.这是一个演示后一种方法的小例子,
Since mutation of global variables is discouraged in Dash, the standard approach to enable access the to current data would be to add a component that holds the data as a State
argument. It could be a separate component (such as a Store
component) or simply the data table itself. Here is a small example demonstrating the latter approach,
import dash
import dash_core_components as dcc
import dash_html_components as html
import dash_table
from dash.dependencies import Output, Input, State
user_key = 'access_token'
# Setup table.
columns = ['report_name', 'ad_account', 'app_id', 'access_token']
table = dash_table.DataTable(columns=[{"name": column, "id": column} for column in columns], data=[], id="table")
# Create app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([dcc.Input(id=column, value=column) for column in columns] +
[html.Button("Save", id="save"), dcc.Store(id="cache", data=[]), table])
@app.callback(Output("table", "data"), [Input("save", "n_clicks")], [State("table", "data")] +
[State(column, "value") for column in columns])
def append(n_clicks, data, *args):
record = {columns[i]: arg for i, arg in enumerate(list(args))}
# If the record (identified by user_key) already exists, update it.
try:
record_index = [record[user_key] for record in data].index(record[user_key])
data[record_index] = record
# Otherwise, append it.
except ValueError:
data.append({columns[i]: arg for i, arg in enumerate(list(args))})
# Return the updated data.
return data
if __name__ == '__main__':
app.run_server()
作为旁注,prevent_initial_callbacks
关键字是 Dash 1.12.0
中的新关键字.顾名思义,它阻止了初始回调,从而消除了对 if clicks is not None:
检查的需要.
As a sidenote, the prevent_initial_callbacks
keyword is new as per Dash 1.12.0
. As indicated by the name, it prevents the initial callback, thereby eliminating the need for the if clicks is not None:
check.
这篇关于Dash App 回调在数据框中追加新条目并替换与任何先前条目匹配的条目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!