测试需求平台6-数据持久化与PyMySQL使用

news2024/11/13 11:34:25

✍此系列为整理分享已完结入门搭建《TPM提测平台》系列的迭代版,拥抱Vue3.0将前端框架替换成字节最新开源的arco.design,其中约60%重构和20%新增内容,定位为从 0-1手把手实现简单的测试平台开发教程,内容将囊括基础、扩展和实战,由浅入深带你实现测试开发岗位中平台工具技术能力入门和提升。

本篇需要提前准备的环境和开发内容:

  • 准备数据库,Mysql5.7+本地或云服务均可
  • 实现后端接口服务的数据库操作

1. 产品数据持久化

在项目管理中,真正的数据需要持久化操作的,这里必然就离不开数据库,本项目使用的Mysql数据库,但不会过多的讲解SQL的内容,只会重点讲解后端服务中Python对于数据库的操作相关知识点。

1.1 数据库和产品表初始化

使用数据库IDE工具链接mysql数据库,并创建一个数据库TPMStore和一个Products表,字段分别如下

使用Navicat可视化创建,或查看笔者大奇之前分享过的一个好用的开源Beekeeper工具

image.png

这里给出SQL语句方便进行表格创建,顺便添加两条正式测试数据

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for products
-- ----------------------------
DROP TABLE IF EXISTS `products`;
CREATE TABLE `products` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '编号自增',
  `keyCode` varchar(200) NOT NULL COMMENT '项目唯一编号',
  `title` varchar(200) NOT NULL COMMENT '中文项目名',
  `desc` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '描述',
  `operator` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '操作者',
  `update` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '操作时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='项目产品表';

-- ----------------------------
-- Records of products
-- ----------------------------
BEGIN;
INSERT INTO `products` VALUES (1, 'data', '数据大盘', '内部一个数据技术分析的项目,用于分析各种数据聚合平台', 'daqi', '2021-07-17 20:38:37');
INSERT INTO `products` VALUES (2, 'payment', '收银台', '支付聚合收银台', 'lili', '2021-07-17 20:40:29');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

1.2 产品查询接口改造

之前的接口 /api/product/list 是硬编码返回,我们这里需要改造成通过数据库查询获得。
python实现mysql的数据的方式目前支持度较好的有:

  • mysqlclient (Star 2.1K+)
  • PyMySQL(Star 7K+)
  • mysql.connector (Mysql官方的驱动库)

以上 github star 数据统计于 2022/07/10

综合使用度和后续可能使用ORM(对象关系映射)优化,本项目选择PyMySQL

# 安装依赖包
python3 -m pip install PyMySQL

然后主要就是引入包,实现数据库的连接和查询操作

# -*- coding:utf-8 -*-
from flask import Blueprint
import pymysql.cursors

app_product = Blueprint("app_product", __name__)

# 使用用户名密码创建数据库链接
connection = pymysql.connect(host='localhost',   # 数据库IP地址或链接域名
                             user='root',     # 设置的具有增改查权限的用户
                             password='******', # 用户对应的密码
                             database='TPMStore',# 数据表
                             charset='utf8mb4',  # 字符编码
                             cursorclass=pymysql.cursors.DictCursor) # 结果作为字典返回游标

@app_product.route("/api/product/list",methods=['GET'])
def product_list():
    # 使用python的with..as控制流语句(相当于简化的try except finally)
    with connection.cursor() as cursor:
        # 查询产品信息表-按更新时间新旧排序
        sql = "SELECT * FROM `Products` ORDER BY `Update` DESC"
        cursor.execute(sql)
        data = cursor.fetchall()

    # 按返回模版格式进行json结果返回
    resp_data = {
        "code": 20000,
        "data": data
    }
    return resp_data

对改造的后的接口用Postman做个验证测试,从下图可以看到数据已经是从product表里查出来的。
image.png

2. PyMySQL使用

PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库。

  • 官方文档 https://pymysql.readthedocs.io
  • 菜鸟教程:https://www.runoob.com/python3/python3-mysql.html

2.1 依赖安装

首先关于安装依赖,上边已经给列出通过$ python3 -m pip install PyMySQL 命令,这里需要特别强调一下,如果你使用的是Mysql 8.x 数据库服务,由于高版本改变了密码加密方式,所以必须安装额外的依赖

# 不兼容加密方式连接报错如下
# RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods
$ python3 -m pip install PyMySQL[rsa]

另外还可以通过改mysql的加密方式为 mysql_native_password,笔者本地版本8.0.25为了方便已经修改了,查询的方法见截图:
image.png

2.2 数据库连接

连接实例的是在代码中import pymysql 后通过.connet(...)方法创建,扒一下源码可以看到有很到参数
image.png
这里捡一些基本的和可能用到的参数做下解释说明

  • host 数据库地址IP或者域名
  • user 数据库分配的账号
  • password 数据库分配的密码
  • database 指定数据库, 可以为None后续使用时候进行切换
  • port 数据库端口号,默认3306
  • read_timeout 读操作超时时间
  • write_timeout 写操作超时时间
  • charset 字符编码中文建议设置utf8等
  • cursorclass 设置返回的数据类型,默认查询返回的数据是tuples元组,一般我们数据多数以table的形式呈现,所以建议设置成cursorclass=MySQLdb.cursors.DictCursor字典类型h
  • connect_timeout 连接超时时间

还有其他如ssl加密相关、连接数设置等,实际项目中按需查阅参数配置。

另外一点在创建db对象后,其实就可以通过游标创建对应的数据库以及切换对应的库。

# 执行创建数据库
cursor.execute("CREATE DATABASE QiDBTest character SET utf8mb4;") 

# 切库或使用 db.select_db("数据库名")
cursor.execute("use QiDBTest;") 

# #可以通过以下语句进行创建查询
# cursor.execute("SHOW DATABASES;")
# print(cursor.fetchall())

2.3 数据库表操作

创建数据库连接对象,然后再创建一个游标对象cursor,通过cursor.excute() 执行对应的语句,就可以进行表相关、数据相关操作,其实excute的操作,你完全可以被看做使用任何一个数据库IDE工具,打开了一个查询面板来执行对应的SQL语句

表创建和数据查询 均通过执行对应的SQL语句实现,其中查询结果还需要通过cursor.fetchall()获取,对应的还有两个常用的

  • cursor.fetchone() 返回一行数据
  • cursor.fetchmany(size) 返回指定数量行
import pymysql
 
# 创建数据库连接
db = pymysql.connect(host='localhost',
                     user='mrzcode',
                     password='mrzcode',
                     database='QiDBTest')
 
# 使用cursor()方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用execute()方法执行 SQL,如果表存在则删除
cursor.execute("DROP TABLE IF EXISTS QiTableDemo")

# 创建表语句
sqlCreateTable = """
    CREATE TABLE `QiTableDemo` (
        `id` bigint NOT NULL AUTO_INCREMENT COMMENT '自增ID',
        `name` varchar(100) NOT NULL COMMENT '名称',
        `desc` varchar(500) COMMENT '描述',
         PRIMARY KEY (`id`)
    )"""

# 执行SQL语句创建表
cursor.execute(sqlCreateTable)

# 验证查询下表情况
cursor.execute("SHOW TABLES;")
print(cursor.fetchall())  # (('qitabledemo',),) 默认元组查询表列表


# 查询QiTableDemo表所有数据
sqlSelect = "SELECT * FROM QiTableDemo;" 

# 执行表查询语句
cursor.execute(sqlSelect)
print(cursor.fetchall())  # () 新表返回一个空的tuples

表数据增删改 额外在execute基础上进行db.commit()提交,如果不提交连接关闭后这些数据修改是不生效的。

import pymysql

# 创建数据库连接
db = pymysql.connect(host='127.0.0.1',
                     user='root****',
                     password='*******',
                     database='QiDBTest',
                     cursorclass=pymysql.cursors.DictCursor)

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

sqlInsert = '''INSERT INTO qitabledemo(`name`,`desc`) VALUES ('插入测试名称', '插入测试描述');'''

# 执行表查询语句
cursor.execute(sqlInsert)

# 对执行提交,这里可以尝试注释掉验证不进行提交数据能否插入
db.commit()

# 查询数据是否正确插入
cursor.execute("select * from qitabledemo;")
print(cursor.fetchall()) # [{'id': 6, 'name': '插入测试名称', 'desc': '插入测试描述'}]

# 关闭数据库连接
db.close()

上边这种sql语句是一个字符串形式,但实际在代码逻辑处理中值一般都是通过变量传递的,所以通过以下两种方式动态赋值

# 方式一:占位拼接字符串
sqlMethod1 = "INSERT INTO qitabledemo(`name`,`desc`) VALUES ('%s', '%s')" % ("占位名称","占位描述")
cursor.execute(sqlMethod1)

# 方式二:通过execute传参
sqlMethod2 = "INSERT INTO qitabledemo(`name`,`desc`) VALUES ('%s', '%s')"
cursor.execute(sqlMethod1,(变量1,变量2))

剩下关于更新、删除的操作同样,只是按需替换成对应的语句,但强调的一点是不要忘记commit,以下给出我这边的例子和验证测试
image.png

2.4 事务和错误处理

**关于事务机制 **可以确保数据一致性,场景主要用于多逻辑交互时候其中操作错误,进行响应的回滚处理,避免产生脏数据,事务通常具有4个属性:原子性、一致性、隔离性、持久性。
对于支持事务的数据库, 在Python数据库编程中,当游标建立之时,就自动开始了一个隐形的数据库事务。

  • commit() 方法游标的所有更新操作;
  • rollback() 方法回滚当前游标的所有操作。

每一个方法都开始了一个新的事务。

sql = "数据库操作的增删改查语句"
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 向数据库提交
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

关于错误 DB API中定义了一些数据库操作的错误及异常(以下引用菜鸟教程),严谨的编程需要对不同的错误进行响应的处理。

异常描述
Warning当有严重警告时触发,例如插入数据被截断等等。必须是 StandardError 的子类。
Error警告以外所有其他错误类。必须是 StandardError 的子类。
InterfaceError当有数据库接口模块本身的错误(而不是数据库的错误)发生时触发。 必须是Error的子类。
DatabaseError和数据库有关的错误发生时触发。 必须是Error的子类。
DataError当有数据处理时的错误发生时触发,例如:除零错误,数据超范围等等。 必须是DatabaseError的子类。
OperationalError指非用户控制的,而是操作数据库时发生的错误。例如:连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是DatabaseError的子类。
IntegrityError完整性相关的错误,例如外键检查失败等。必须是DatabaseError子类。
InternalError数据库的内部错误,例如游标(cursor)失效了、事务同步失败等等。 必须是DatabaseError子类。
ProgrammingError程序错误,例如数据表(table)没找到或已存在、SQL语句语法错误、 参数数量错误等等。必须是DatabaseError的子类。
NotSupportedError不支持错误,指使用了数据库不支持的函数或API等。例如在连接对象上 使用.rollback()函数,然而数据库并不支持事务或者事务已关闭。 必须是DatabaseError的子类。

2.6 新手操作指南

最后总结一下一般Python使用PyMySQL的编程步骤

  1. 引用模块库
  2. 创建连接对象db=connect(…)
  3. 从连接对象获取游标cursor=db.cursor()
  4. 准备sql语句并通过游标执行cursor.execute(sql)
  5. 如果是非查询动作还需要db.commit()
  6. 关闭数据库连接db.close()

以上就是本篇的主要内容,重点讲解Python 对mysql数据库的操作,并且开始就开门见山地做个了项目实战,相信这些内容掌握了,本系列项目中有关数据操作部分都会游刃有余。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/453796.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

信息安全技术 健康医疗数据安全指南 付下载地址

声明 本文是学习GB-T 39725-2020 信息安全技术 健康医疗数据安全指南. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 数据使用管理办法示例 第一章 总则 第一条 为规范数据使用流程,根据国家相关法律法规及相关规定,特制定本…

imgaug Augment Polygons 对标注图片和polygons的数据增强

对于本地化进行图像的增强,大家都是非常好操作的。但是,对于标注信息一起增强,还是稍微有一些难度的,麻烦很多。 我是遇到一个数据集非常少的任务,只有40张图。就直接标记了去训练,发现几乎不拟合&#xf…

这一篇搞定Spring

文章目录 一、引言1.1 原生web开发中存在哪些问题? 二、Spring框架2.1 概念2.2 访问与下载 三、Spring架构组成四、山寨版的Spring容器4.1准备工作4.2 山寨IOC容器4.3 配置文件告诉容器 管理哪些bean4.4 相关类4.5 测试 容器 五、构建Maven项目5.1 新建项目5.2 选择…

深度强化学习——AlphaGo实例讲解(5)

现在我们来分析AlphaGo这个实例,看看深度强化学习是怎么样用来玩围棋游戏的 AlphaGo的主要设计思路: 首先是训练,要分3步来做: 1、behavior cloning:这是一种模仿学习,alphaGo模仿人类玩家,从…

STM32平衡小车 pid简单学习

自动控制系统 自动控制系统可分为开环控制系统和闭环控制系统。 1、开环控制系统开环控制系统(open-loop control system)指被控对象的输出(被控制量)对控制器(controller)的输出没有影响。在这种控制系统中,不依赖将被控量反送回来以形成任何闭环回路。 2、闭环控…

c++入门(下)

C入门(下) 对于C的基础语法的讲解,由想要实现多次重复的函数,引出宏函数和inline的内联函数的对比,对于inline的讲解和运用,在后,C语言中的NULL和C中独特的nullptr的相比两者的比较&#xff0c…

kong(4):限流配置

Kong 提供了 Rate Limiting 插件,实现对请求的限流功能,避免过大的请求量过大,将后端服务打挂。 Rate Limiting 支持秒/分/小时/日/月/年多种时间维度的限流,并且可以组合使用。例如说:限制每秒最 多 100 次请求&…

Windows Server 2012R2 安装mysql 丢失VCRUNTIME140_1.dll------亲测

无去启动此程序,因为计算机中丢失VCRUNTIME140_1.dll。尝试重新安装该程序以解决此问题。 1.解决思路 说到底还是缺少底层的依赖,先下载依赖然后安装,最后安装vc。要不然vc是安装不成功。 下载安装--一下的插件 安装过程中需要重启一次电脑。 注意:必…

Android LoaderManager AsyncTaskLoader加载全部图片RecyclerView BigImageView呈现,Java(1)

Android LoaderManager AsyncTaskLoader加载全部图片RecyclerView BigImageView呈现&#xff0c;Java&#xff08;1&#xff09; 权限&#xff1a; <uses-permission android:name"android.permission.READ_EXTERNAL_STORAGE" /><uses-permission android:n…

VUE3子组件-业务代码优化

Vue3子组件 1.简介 Vue 3组件的主要优势之一就是它们可以帮助你将你的应用程序分解成可维护和可重用的部分。当你在应用程序中多次使用相同的代码时&#xff0c;你可以将它们抽象成一个组件&#xff0c;然后在应用程序中的多个地方使用该组件&#xff0c;而不必每次都编写相同…

5年了,终于入职阿里测试岗位,直接涨薪30K...

前言 本科毕业后就一直从事软件测试的工作&#xff0c;和多数人一样&#xff0c;最开始从事功能测试的工作&#xff0c;看着自己的同学一步一步往上走&#xff0c;自己还是在原地踏步&#xff0c;说实话这不是自己想要的状态。 一年半后开始沪漂生活&#xff0c;又摸爬滚打了…

阿里巴巴软件测试面试过了,起薪20k

普通二本计算机专业毕业&#xff0c;从毕业后&#xff0c;第一份接触测试的工作是在一家通讯小公司&#xff0c;大部分接触的工作是以功能测试为主&#xff0c;一直都是几千块钱工资&#xff0c;还一度被派出差&#xff0c;以及兼职各种产品、运维、运营的活&#xff0c;感觉自…

Cleer ARC II 音弧

戴上Cleer ARC II 音弧解放双耳&#xff0c;享受更自由的音符 用惯了各种入耳式耳机&#xff0c;换上开放式耳机&#xff0c;戴着确实更加舒服&#xff0c;特别是我现在用的这款Cleer ARC II 音弧&#xff0c;戴上还不容易掉&#xff0c;很适合运动使用。这款耳机采用一种耳挂佩…

JavaEE1(4/23)

目录 1.计算机CPU 2.CPU和GPU的区别 3.线程 4.内存是如何分配的 5.进程的调度 6.线程和进程的区别和联系&#xff1f; 1.计算机CPU 主频 &#xff1a;运算速度 3.73Ghz 表示每秒计算37.3亿次 基准速度&#xff1a;最小计算速度 睿频&#xff1a;最大运行速度 超频&…

【头歌C语言程序设计】结构体解答

写在前面 这道题总体来说还是偏难的&#xff0c;如果只看代码比较难以理解&#xff0c;当结构体的文章发出后&#xff0c;就有许多小伙伴问我这个问题&#xff0c;我开始意识到&#xff0c;可能我对这道题所作的解答还不够&#xff08;不装了&#x1f601;&#xff0c;根本没有…

Python进阶篇(三)-- TCP套接字与UDP套接字编程

1 Python3 网络编程 1.1 介绍 本文将首先利用 Python 实现面向TCP连接的套接字编程基础知识&#xff1a;如何创建套接字&#xff0c;将其绑定到特定的地址和端口&#xff0c;以及发送和接收数据包。其次还将学习 HTTP 协议格式的相关知识。在此基础上&#xff0c;本篇将用 Pyt…

Spring boot项目编译后未能加载静态资源文件

起因: 因甲方爸爸加了一个紧急的需求: 需要搞一个文件上传和下载功能. 我心中想:这不简单,搞个资源服务器,将上传文件放上去,然后访问资源链接就行了. 但接下来甲方爸爸说 不需要这莫麻烦,直接将文件放服务器里,用的时候下载到资源文件夹下就行. 我心里想: 我擦嘞 还能这样!! 然…

【C++】—— STL简介(了解)

前言&#xff1a; 在上节&#xff0c;我们简单的认识了模板的基本概念。今天我简单的给大家介绍一下关于 STL 。 目录 &#xff08;一&#xff09; 什么是STL &#xff08;二&#xff09; STL的版本 &#xff08;三&#xff09; STL的六大组件 &#xff08;四&#xff09;…

Tomcat概述以及部署与优化

一、Tomcat概述 1、Tomcat的概念 Tomcat是Java语言开发的&#xff0c;服务器是一个免费的开放源代码的Web应用服务器&#xff0c;属于轻量级应用服务器&#xff0c;在中小型系统和并发访问用户不是很多的场合下被普遍使用&#xff0c;是开发和调试JSP程序的首选。一般来说&am…

Python入门基础小练习

通过前面的两个篇章Python-入门基础篇和Python-入门基础语句篇大家应该已经认识了python基础的语句和函数了&#xff0c;并且可以使用pycharm编译器创建.py文件进行运行了&#xff0c;今天适当的来一些小练习&#xff0c;给枯燥的学习增添一些趣味性。 判断一个数是否为偶数 …