本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes

1 简介

这是我的系列教程「Python+Dash快速web应用开发」的第十三期,在上一期中,我们一起认识了Dash自带的交互式表格组件dash_table,并学会了如何自定义表格中不同部分的样式。

而今天的教程,我们将继续深入认识dash_table的更多交互方面的功能,学习如何为渲染出的表格分页,并添加动态内容修改等交互功能。

图1

2 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万行,加载应用以及网页内翻页时依然轻松自如毫无压力,在实际应用中你还可以将翻页部分改成受到LIMITOFFSET控制的数据库查询过程,使得应用运行的更加快速高效:

图3

2.2 对单元格内容进行编辑

讲完了分页翻页,接下来我们来学习dash_table中更加强大的功能——单元格内容编辑。

一个现代化的web应用当然不能局限于仅仅查看数据这么简单,Dash同样赋予了我们双击数据表单元格进行数据编辑的能力,首先得设置参数editable=True,即开启表格编辑模式,接下来就可以对数据区域单元格进行任意的双击选中编辑。

不过Dash默认的单元格被选中的样式忒丑了(是粉色的你敢信),因此我们可以利用下面的参数设置方式来自定义美化:

style_data_conditional=[{# 对选中状态下的单元格进行自定义样式"if": {"state": "selected"},"background-color": "#b3e5fc","border": "none"},]

来看一个形象的例子,我们对「前端分页」方式渲染出的表格进行随意的修改,并在下方对利用pandascompare比较出的数据框之间的差异结果进行打印:

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)

可以看到,我们成功地对指定单元格元素进行了修改。

图4

3 开发数据库内容在线更新工具

在学习完今天的内容之后,我们就可以开发一个简单的,可在线自由修改并同步变动到数据库的小工具,这里我们以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快速开发在线数据库更新修改工具相关推荐

  1. 用python快速开发一个实用的socket服务器

    用python快速开发一个实用的socket服务器 - 吴尔平 - 博客园 用python快速开发一个实用的socket服务器 首先,要明白不是所有的socket服务都需要高性能.如果要求高性能,使用 ...

  2. 使用ruby和python快速开发metasploit自定义模块

    使用ruby和python快速开发metasploit自定义模块 前言 本文的内容主要分为两个部分: 提供一个基本ruby模块代码框架,并快速开发自定义ruby模块 提供一个基本python模块代码框 ...

  3. Python Web 开发 – 在线web计算器

    Python Web 开发 – 在线web计算器 本文环境: Python-3.10.2 Visual Studio Code-1.65.2 Django-4.0.3 Bootstrap-5.1.3 ...

  4. python快速开发游戏_快速游戏开发的10个关键

    python快速开发游戏 10月初,由Opensource.com赞助的首届Open Jam吸引了来自全球团队的45个参赛作品. 参赛队伍只有三天的时间使用开放源代码软件来创建游戏,并参加了比赛, 最 ...

  5. Android快速开发不可或缺的11个工具类(下载)

    Android快速开发不可或缺的11个工具类(下载) 源码简介 Android快速开发不可或缺的11个辅助类,其中10个来自张鸿洋的博客,1个是我平时积攒的,复制粘贴到你的项目里,添加上包名就可以直接 ...

  6. MATLAB /Simulink 快速开发STM32(使用st官方工具 STM32-MAT/TARGET)

    MATLAB /Simulink 快速开发STM32(使用st官方工具 STM32-MAT/TARGET) 置顶 2018年06月04日 22:10:24 siemens_xp 阅读数 7220 在网 ...

  7. 在线网页更新检查工具

    好用的在线网页更新检查工具AOTOL<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office&q ...

  8. 用python写web网页_从零开始,使用python快速开发web站点(1) | 学步园

    环境:ubuntu 12.04 python版本:  2.73 ok,首先,既然是从零开始,我们需要的是一台可以运行的python的计算机环境,并且假设你已经安装好了python, 然后,既然是快速开 ...

  9. 实用 | 利用 aardio 配合 Python 快速开发桌面应用

    1. 前言 我们都知道 Python 可以用来开发桌面应用,一旦功能开发完成,最后打包的可执行文件体积大,并且使用 Python 开发桌面应用周期相对较长 假如想快速开发一款 PC 端的桌面应用,推荐 ...

最新文章

  1. 基于visual Studio2013解决面试题之0901奇偶站队
  2. css图片和文字一样高,css里图片和文字如何等高
  3. 孰优孰劣?Dubbo VS Spring Cloud性能测试大对决!
  4. python【蓝桥杯vip练习题库】ADV-73数组输出
  5. stm32l0的停止模式怎么唤醒_最强家庭娱乐系统+儿童模式,小度在家智能屏X8开售抢先体验...
  6. Eclipse最新版 Neon已发布
  7. 该虚拟机似乎正在使用中 请获取所有权
  8. windows下使用命令行将employees.sql导入mysql
  9. Community Server架构:博客业务详细分析(转)
  10. 男生计算机学校,杭州2021年男生读什么计算机学校
  11. redis 中一个字段 修改map_Redis中bitmap的妙用
  12. GO语言Comma-ok断言
  13. 基于微信小程序开发的在线答题系统
  14. 一块蛋清皂,把毛孔洗得一干二净
  15. python 求定积分
  16. 自制合成孔径雷达(3) doppler代码解读
  17. spring boot网上购物系统毕业设计源码311236
  18. 中年程序员失业的3条退路!
  19. cynthai原班人马开发的团队协作平台effevo(effevo.com)免费开放了!
  20. matlab中枝切法解包裹,一种基于改进枝切法的激光散斑相位解包裹方法与流程

热门文章

  1. Java——遍历List过程中添加和删除元素的问题(亲测第二种)
  2. PHP的Composer:命令 符号 区别
  3. Laravel表单提交419页面过期
  4. Go的RESTful
  5. Curl http_code 状态码
  6. PHP中empty,is_null,isset的区别
  7. MySQL中的时间函数用法集合
  8. JavaScript中的匿名函数及函数的闭包
  9. html图片上传选择文件后的事件,bootstrap-fileinput插件,上传成功后事件
  10. python写数据库校验_python 验证 sqlite数据库隔离级别