秀啊,用Python快速开发在线数据库更新修改工具
本文示例代碼已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes
?1 簡介
這是我的系列教程「Python+Dash快速web應用開發」的第十三期,在上一期中,我們一起認識了Dash自帶的交互式表格組件dash_table,并學會了如何自定義表格中不同部分的樣式。
而今天的教程,我們將繼續深入認識dash_table的更多交互方面的功能,學習如何為渲染出的表格分頁,并添加動態內容修改等交互功能。
圖12 dash_table的基礎交互能力
dash_table的核心功能是賦予用戶與圖表進行快捷交互的能力,下面我們來學習其基礎常用的一些交互功能:
2.1 分頁翻頁
當我們要展示的數據行數較多時,在網頁中渲染可以選擇分頁,這在dash_table中實現起來比較方便,根據數據傳遞方式的不同,可以分為「前端分頁」與「后端分頁」:
2.1.1 前端分頁
前端分頁顧名思義,就是在我們訪問Dash應用時,表格內所有頁面的數據一次性加載完成,適合數據量不大的情況,將數據存儲壓力轉移到瀏覽器端。
通過參數page_size設置每頁要顯示的記錄行數,Dash會自動幫我們分好頁,并配上翻頁部件:
?app1.py
?import?dash import?dash_bootstrap_components?as?dbc import?dash_tableimport?seaborn?as?snsdf?=?sns.load_dataset('tips') df.insert(0,?'#',?df.index)app?=?dash.Dash(__name__)app.layout?=?dbc.Container([dash_table.DataTable(id='dash-table',data=df.to_dict('records'),columns=[{'name':?column,?'id':?column}for?column?in?df.columns],page_size=15,??#?設置單頁顯示15行記錄行數style_header={'font-family':?'Times?New?Romer','font-weight':?'bold','text-align':?'center'},style_data={'font-family':?'Times?New?Romer','text-align':?'center'})],style={'margin-top':?'50px'} )if?__name__?==?'__main__':app.run_server(debug=True) 圖2### 2.1.2 后端分頁
雖然前端分頁簡單易用,但當我們的數據很大時,強行使用前端分頁會給「網絡傳輸」和「瀏覽器端」帶來不小的延遲和內存壓力,嚴重影響用戶體驗,因此Dash貼心地為我們準備了「后端分頁」方式。
這時首先我們得為DataTable設置參數page_action='custom',這是使用后端分頁的先決條件,接下來我們需要認識一些新的參數:
page_current,int型,對應當前翻到的頁碼;
page_count,int型,對應顯示的總頁數;
我們在使用「后端分頁」時,實際上就是通過用戶當前翻到的頁碼,以及設定的page_size,來動態地在翻頁后加載對應批次的數據,并控制顯示的總頁數,參考下面這個簡單的例子:
?app2.py
?import?dash import?dash_bootstrap_components?as?dbc import?dash_table from?dash.dependencies?import?Input,?Outputimport?seaborn?as?sns import?pandas?as?pd from?tqdm?import?tqdm#?壓力測試 df?=?pd.concat([sns.load_dataset('tips')?for?_?in?tqdm(range(1000))],?ignore_index=True) df.insert(0,?'#',?df.index)app?=?dash.Dash(__name__)app.layout?=?dbc.Container([dbc.Spinner(dash_table.DataTable(id='dash-table',columns=[{'name':?column,?'id':?column}for?column?in?df.columns],page_size=15,??#?設置單頁顯示15行記錄行數page_action='custom',page_current=0,style_header={'font-family':?'Times?New?Romer','font-weight':?'bold','text-align':?'center'},style_data={'font-family':?'Times?New?Romer','text-align':?'center'}))],style={'margin-top':?'50px'} )@app.callback([Output('dash-table',?'data'),Output('dash-table',?'page_count')],[Input('dash-table',?'page_current'),Input('dash-table',?'page_size')] ) def?refresh_page_data(page_current,?page_size):return?df.iloc[page_current?*?page_size:(page_current?+?1)?*?page_size].to_dict('records'),?1?+?df.shape[0]?//?page_sizeif?__name__?==?'__main__':app.run_server(debug=True)可以看到,即使我們完整的數據集被我concat到24萬行,加載應用以及網頁內翻頁時依然輕松自如毫無壓力,在實際應用中你還可以將翻頁部分改成受到LIMIT與OFFSET控制的數據庫查詢過程,使得應用運行的更加快速高效:
圖32.2 對單元格內容進行編輯
講完了分頁翻頁,接下來我們來學習dash_table中更加強大的功能——單元格內容編輯。
一個現代化的web應用當然不能局限于僅僅查看數據這么簡單,Dash同樣賦予了我們雙擊數據表單元格進行數據編輯的能力,首先得設置參數editable=True,即開啟表格編輯模式,接下來就可以對數據區域單元格進行任意的雙擊選中編輯。
不過Dash默認的單元格被選中的樣式忒丑了(是粉色的你敢信),因此我們可以利用下面的參數設置方式來自定義美化:
style_data_conditional=[{#?對選中狀態下的單元格進行自定義樣式"if":?{"state":?"selected"},"background-color":?"#b3e5fc","border":?"none"},]來看一個形象的例子,我們對「前端分頁」方式渲染出的表格進行隨意的修改,并在下方對利用pandas的compare比較出的數據框之間的差異結果進行打印:
?app3.py
?import?dash import?dash_html_components?as?html import?dash_core_components?as?dcc import?dash_bootstrap_components?as?dbc import?dash_table from?dash.dependencies?import?Input,?Outputimport?seaborn?as?sns import?pandas?as?pddf?=?sns.load_dataset('tips') df.insert(0,?'#',?df.index)app?=?dash.Dash(__name__)app.layout?=?dbc.Container([dash_table.DataTable(id='dash-table',data=df.to_dict('records'),columns=[{'name':?column,?'id':?column}for?column?in?df.columns],fixed_rows={'headers':?True},page_size=15,editable=True,style_header={'font-family':?'Times?New?Romer','font-weight':?'bold','text-align':?'center'},style_data={'font-family':?'Times?New?Romer','text-align':?'center'},style_data_conditional=[{#?對選中狀態下的單元格進行自定義樣式"if":?{"state":?"selected"},"background-color":?"#b3e5fc","border":?"none"},]),html.H4('與原表格內容比較:',?style={'margin-top':?'50px'}),dcc.Markdown('無差別',id='markdown',dangerously_allow_html=True)],style={'margin-top':?'50px'} )@app.callback(Output('markdown',?'children'),Input('dash-table',?'data'),prevent_initial_call=True ) def?compare_difference(dash_table_data):print(pd.DataFrame(dash_table_data))return?df.compare(pd.DataFrame(dash_table_data)).to_html()if?__name__?==?'__main__':app.run_server(debug=True)可以看到,我們成功地對指定單元格元素進行了修改。
圖43 開發數據庫內容在線更新工具
在學習完今天的內容之后,我們就可以開發一個簡單的,可在線自由修改并同步變動到數據庫的小工具,這里我們以MySQL數據庫為例,對示例表進行修改和更新:
首先我們利用下列代碼向示例數據庫中新建表格tips:
from?sqlalchemy?import?create_engine import?seaborn?as?snsdf?=?sns.load_dataset('tips') df.insert(0,?'#',?df.index)engine?=?create_engine('mysql+pymysql://root:mysql@localhost/DASH')df.to_sql('tips',?con=engine,?if_exists='replace',?index=False) 圖5接下來我們就以創建好的tips表為例,開發一個Dash應用,進行數據的修改和更新到數據庫:
圖6效果非常的不錯,你可以在我這個簡單示例的基礎上,拓展更多新功能,也可以采取后端分頁+條件修改的方式來應對大型數據表的修改,全部代碼如下:
?app4.py
?import?dash import?dash_bootstrap_components?as?dbc import?dash_core_components?as?dcc import?dash_html_components?as?html import?dash_table from?dash.dependencies?import?Input,?Output,?Statefrom?sqlalchemy?import?create_engine import?pandas?as?pdengine?=?create_engine('mysql+pymysql://root:mysql@localhost/DASH')app?=?dash.Dash(__name__)app.layout?=?dbc.Container([dbc.Row([dbc.Col(dbc.Button('更新數據表',?id='refresh-tables',?style={'width':?'100%'}),?width=2),dbc.Col(dcc.Dropdown(id='table-select',?style={'width':?'100%'}),?width=2)]),html.Hr(),dash_table.DataTable(id='dash-table',editable=True,page_size=15,style_header={'font-family':?'Times?New?Romer','font-weight':?'bold','text-align':?'center'},style_data={'font-family':?'Times?New?Romer','text-align':?'center'},style_data_conditional=[{#?對選中狀態下的單元格進行自定義樣式"if":?{"state":?"selected"},"background-color":?"#b3e5fc","border":?"none"},]),dbc.Button('同步變動到數據庫',?id='update-tables',?style={'display':?'none'}),html.P(id='message')],style={'margin-top':?'50px'} )@app.callback(Output('table-select',?'options'),Input('refresh-tables',?'n_clicks') ) def?refresh_tables(n_clicks):if?n_clicks:return?[{'label':?table,'value':?table}for?table?in?pd.read_sql_query('SHOW?TABLES',?con=engine)['Tables_in_dash']]return?dash.no_update@app.callback([Output('dash-table',?'data'),Output('dash-table',?'columns'),Output('update-tables',?'style')],Input('table-select',?'value') ) def?render_dash_table(value):if?value:df?=?pd.read_sql_table(value,?con=engine)return?df.to_dict('records'),?[{'name':?column,?'id':?column}for?column?in?df.columns],?{'margin-top':?'25px'}else:return?[],?[],?{'display':?'none'}@app.callback([Output('message',?'children'),Output('message',?'style')],Input('update-tables',?'n_clicks'),[State('dash-table',?'data'),State('table-select',?'value')] ) def?update_to_database(n_clicks,?data,?value):if?n_clicks:try:pd.DataFrame(data).to_sql(value,?con=engine,?if_exists='replace',?index=False)return?'更新成功!',?{'color':?'green'}except?Exception?as?e:return?f'更新失敗!{e}',?{'color':?'red'}return?dash.no_updateif?__name__?==?'__main__':app.run_server(debug=True)以上就是本文的全部內容,歡迎在評論區發表你的意見與觀點。
推薦閱讀 誤執行了rm -fr /*之后,除了跑路還能怎么辦?!程序員必備58個網站匯總大幅提高生產力:你需要了解的十大Jupyter Lab插件總結
以上是生活随笔為你收集整理的秀啊,用Python快速开发在线数据库更新修改工具的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员公开上班摸鱼神器!有了它,老板都不
- 下一篇: 一文秒懂!Python字符串格式化之fo