秀啊,用Python快速开发在线数据库更新修改工具

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: 秀啊,用Python快速开发在线数据库更新修改工具

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_table
import seaborn as sns
df = 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, Output
import 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_size
if __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, Output
import seaborn as sns
import pandas as pd
df = 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 sns
df = 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, State
from sqlalchemy import create_engine
import pandas as pd
engine = 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_update
if __name__ == '__main__':
    app.run_server(debug=True)
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
存储 缓存 Shell
你知道 Python 其实自带了小型数据库吗
你知道 Python 其实自带了小型数据库吗
10 2
你知道 Python 其实自带了小型数据库吗
|
1天前
|
网络协议 IDE iOS开发
Python编程---简单的聊天工具
Python编程---简单的聊天工具
12 2
|
5天前
|
数据处理 开发者 Python
Python编程中的列表推导式:简洁而强大的工具
【9月更文挑战第35天】在Python的众多特性中,列表推导式以其简明扼要和强大功能脱颖而出。本文不仅将介绍列表推导式的基础知识,还将探讨其背后的逻辑,并辅以实际代码示例。无论你是初学者还是有经验的开发者,都能从中获取新的见解和应用技巧。
15 5
|
2天前
|
前端开发 Java 数据库连接
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
本文是一份全面的表白墙/留言墙项目教程,使用SpringBoot + MyBatis技术栈和MySQL数据库开发,涵盖了项目前后端开发、数据库配置、代码实现和运行的详细步骤。
7 0
表白墙/留言墙 —— 中级SpringBoot项目,MyBatis技术栈MySQL数据库开发,练手项目前后端开发(带完整源码) 全方位全步骤手把手教学
|
11天前
|
测试技术 Python
Python MagicMock: Mock 变量的强大工具
Python MagicMock: Mock 变量的强大工具
26 8
|
11天前
|
数据采集 关系型数据库 MySQL
如何用Python+sqlalchemy创建数据库
如何用Python+sqlalchemy创建数据库
25 2
|
2天前
|
搜索推荐 BI API
ZoomEye-python工具使用详解(一)
ZoomEye-python工具使用详解(一)
|
2天前
|
存储 缓存 JSON
ZoomEye-python工具使用详解(二)
ZoomEye-python工具使用详解(二)
13 0
|
2天前
|
安全 网络安全 数据安全/隐私保护
Python渗透测试之流量分析:流量嗅探工具编程
Python渗透测试之流量分析:流量嗅探工具编程
11 0
|
2天前
|
缓存 监控 程序员
Python装饰器:深入探索功能增强的神奇工具(特点+应用+举例)
Python装饰器:深入探索功能增强的神奇工具(特点+应用+举例)
6 0