秀啊,用Python快速开发在线数据库更新修改工具
本文示例代碼已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes
?1 簡介
這是我的系列教程「Python+Dash快速web應(yīng)用開發(fā)」的第十三期,在上一期中,我們一起認(rèn)識了Dash自帶的交互式表格組件dash_table,并學(xué)會了如何自定義表格中不同部分的樣式。
而今天的教程,我們將繼續(xù)深入認(rèn)識dash_table的更多交互方面的功能,學(xué)習(xí)如何為渲染出的表格分頁,并添加動態(tài)內(nèi)容修改等交互功能。
圖12 dash_table的基礎(chǔ)交互能力
dash_table的核心功能是賦予用戶與圖表進(jìn)行快捷交互的能力,下面我們來學(xué)習(xí)其基礎(chǔ)常用的一些交互功能:
2.1 分頁翻頁
當(dāng)我們要展示的數(shù)據(jù)行數(shù)較多時,在網(wǎng)頁中渲染可以選擇分頁,這在dash_table中實現(xiàn)起來比較方便,根據(jù)數(shù)據(jù)傳遞方式的不同,可以分為「前端分頁」與「后端分頁」:
2.1.1 前端分頁
前端分頁顧名思義,就是在我們訪問Dash應(yīng)用時,表格內(nèi)所有頁面的數(shù)據(jù)一次性加載完成,適合數(shù)據(jù)量不大的情況,將數(shù)據(jù)存儲壓力轉(zhuǎn)移到瀏覽器端。
通過參數(shù)page_size設(shè)置每頁要顯示的記錄行數(shù),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,??#?設(shè)置單頁顯示15行記錄行數(shù)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 后端分頁
雖然前端分頁簡單易用,但當(dāng)我們的數(shù)據(jù)很大時,強(qiáng)行使用前端分頁會給「網(wǎng)絡(luò)傳輸」和「瀏覽器端」帶來不小的延遲和內(nèi)存壓力,嚴(yán)重影響用戶體驗,因此Dash貼心地為我們準(zhǔn)備了「后端分頁」方式。
這時首先我們得為DataTable設(shè)置參數(shù)page_action='custom',這是使用后端分頁的先決條件,接下來我們需要認(rèn)識一些新的參數(shù):
page_current,int型,對應(yīng)當(dāng)前翻到的頁碼;
page_count,int型,對應(yīng)顯示的總頁數(shù);
我們在使用「后端分頁」時,實際上就是通過用戶當(dāng)前翻到的頁碼,以及設(shè)定的page_size,來動態(tài)地在翻頁后加載對應(yīng)批次的數(shù)據(jù),并控制顯示的總頁數(shù),參考下面這個簡單的例子:
?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,??#?設(shè)置單頁顯示15行記錄行數(shù)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)可以看到,即使我們完整的數(shù)據(jù)集被我concat到24萬行,加載應(yīng)用以及網(wǎng)頁內(nèi)翻頁時依然輕松自如毫無壓力,在實際應(yīng)用中你還可以將翻頁部分改成受到LIMIT與OFFSET控制的數(shù)據(jù)庫查詢過程,使得應(yīng)用運行的更加快速高效:
圖32.2 對單元格內(nèi)容進(jìn)行編輯
講完了分頁翻頁,接下來我們來學(xué)習(xí)dash_table中更加強(qiáng)大的功能——單元格內(nèi)容編輯。
一個現(xiàn)代化的web應(yīng)用當(dāng)然不能局限于僅僅查看數(shù)據(jù)這么簡單,Dash同樣賦予了我們雙擊數(shù)據(jù)表單元格進(jìn)行數(shù)據(jù)編輯的能力,首先得設(shè)置參數(shù)editable=True,即開啟表格編輯模式,接下來就可以對數(shù)據(jù)區(qū)域單元格進(jìn)行任意的雙擊選中編輯。
不過Dash默認(rèn)的單元格被選中的樣式忒丑了(是粉色的你敢信),因此我們可以利用下面的參數(shù)設(shè)置方式來自定義美化:
style_data_conditional=[{#?對選中狀態(tài)下的單元格進(jìn)行自定義樣式"if":?{"state":?"selected"},"background-color":?"#b3e5fc","border":?"none"},]來看一個形象的例子,我們對「前端分頁」方式渲染出的表格進(jìn)行隨意的修改,并在下方對利用pandas的compare比較出的數(shù)據(jù)框之間的差異結(jié)果進(jìn)行打印:
?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=[{#?對選中狀態(tài)下的單元格進(jìn)行自定義樣式"if":?{"state":?"selected"},"background-color":?"#b3e5fc","border":?"none"},]),html.H4('與原表格內(nèi)容比較:',?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)可以看到,我們成功地對指定單元格元素進(jìn)行了修改。
圖43 開發(fā)數(shù)據(jù)庫內(nèi)容在線更新工具
在學(xué)習(xí)完今天的內(nèi)容之后,我們就可以開發(fā)一個簡單的,可在線自由修改并同步變動到數(shù)據(jù)庫的小工具,這里我們以MySQL數(shù)據(jù)庫為例,對示例表進(jìn)行修改和更新:
首先我們利用下列代碼向示例數(shù)據(jù)庫中新建表格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接下來我們就以創(chuàng)建好的tips表為例,開發(fā)一個Dash應(yīng)用,進(jìn)行數(shù)據(jù)的修改和更新到數(shù)據(jù)庫:
圖6效果非常的不錯,你可以在我這個簡單示例的基礎(chǔ)上,拓展更多新功能,也可以采取后端分頁+條件修改的方式來應(yīng)對大型數(shù)據(jù)表的修改,全部代碼如下:
?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('更新數(shù)據(jù)表',?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=[{#?對選中狀態(tài)下的單元格進(jìn)行自定義樣式"if":?{"state":?"selected"},"background-color":?"#b3e5fc","border":?"none"},]),dbc.Button('同步變動到數(shù)據(jù)庫',?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)以上就是本文的全部內(nèi)容,歡迎在評論區(qū)發(fā)表你的意見與觀點。
推薦閱讀 誤執(zhí)行了rm -fr /*之后,除了跑路還能怎么辦?!程序員必備58個網(wǎng)站匯總大幅提高生產(chǎn)力:你需要了解的十大Jupyter Lab插件總結(jié)
以上是生活随笔為你收集整理的秀啊,用Python快速开发在线数据库更新修改工具的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员公开上班摸鱼神器!有了它,老板都不
- 下一篇: 一文秒懂!Python字符串格式化之fo