测试需求平台7-产品管理服务接口一篇搞定

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

基于前几篇有关Flask API使用教程、Blueprint路由优化、数据持久化PyMySQL使用的知识内容,本篇就可以很轻松的实现《测试需求平台》中产品模块管理所需要的所有接口服务了。

1.封装数据连接

在正式过实现接口服务之前,我们需要先封装下之前做数据连接操作写在外边的对象代码,因为多方法中如增、改、删使用完后会关闭数据库连接,所以不能一次声明到处使用,我们需要在每次接口请求处理业务前,进行新的数据库初始化,保证数据库连接实例可用。

# 数据库连接方法
def connectDB():connection = pymysql.connect(host='127.0.0.1',   user='mrzcode',password='mrzcode',database='TPMStore',charset='utf8mb4', cursorclass=pymysql.cursors.DictCursor) # 返回新数据库连接对象return connection

最简单的方式就是提取出一个公共方法,每个接口方法实现的时候只需调用重新实例化即可,这个定义就直接在product.py 顶部实现。

当然对于数据管理还可以提取配置文件、使用连接池等方式进一步优化,不过学习总要有个循序渐进的过程,当前先卖个关子,后续会详细讲到。

2. 产品管理接口

2.1 添加接口

基于之前实现的产品查询接口类 product.py 实现产品信息添加接口,基础关键定义如下:

  • methods 定义为POST请求
  • flask request模块的get_data()获取body
  • json 请求处理请求的JSON格式数据

新增依赖引用,其中json是一种轻量级的数据交换格式。

from flask import request
import json

在实现产品新增信息落库之前要增加一个查询判断是否已经存在的逻辑,需求上定义keyCode是关键词,名称可以相同不做特殊处理,如果重复给出提示,code 定义20001,代码中千万不要忘记上节数据操作的commit动作。

# [POST方法]实现新建数据的数据库插入
@app_product.route("/api/product/create",methods=['POST'])
def product_create():# 初始化数据库链接connection = connectDB()# 定义默认返回结构体resp_data = {"code": 20000,"message": "success","data": []}# 获取请求传递json bodybody = request.get_data()body = json.loads(body)with connection:# 先做个查询,判断keyCode是否重复(这里的关键词最初定义为唯一项目编号或者为服务的应用名)with connection.cursor() as cursor:select = "SELECT * FROM `products` WHERE `keyCode`=%s"cursor.execute(select, (body["keyCode"],))result = cursor.fetchall()# 有数据说明存在相同值,封装提示直接返回if len(result) > 0:resp_data["code"] = 20001resp_data["message"] = "唯一编码keyCode已存在"return resp_datawith connection.cursor() as cursor:# 拼接插入语句,并用参数化%s构造防止基本的SQL注入# 其中id为自增,插入数据默认数据设置的当前时间sql = "INSERT INTO `products` (`keyCode`,`title`,`desc`,`operator`) VALUES (%s,%s,%s,%s)"cursor.execute(sql, (body["keyCode"], body["title"], body["desc"], body["operator"]))# 提交执行保存插入数据connection.commit()# 按返回模版格式进行json结果返回return resp_data

以上编写完成再次用ide或者命令运行 app.py 启动后端程序,用postman接口测试工具进行请求测试,验证产品新增接口服务两种逻辑情况
1)符合条件请求验证数据正确落库
image.png

2)KeyCode已经存在验证返回提示image.png特别说明一下,本系列练手项目不会过多做比如边界值、接口参数缺失等这类信息,毕竟前后端都一个人开发,配合约定有一端处理不出现上述情况即可,不过如果在实际工作项目中多人开发的时候,后端的接口相关的必要验证处理还是建议写的。

2.2 修改接口

产品信息修改与插入的代码逻辑几乎一样,只是请求Body需要而外带过来插入自动生成的ID,并将语句换成了UPDATE语法。

# [POST方法]根据项目ID进行信息更新
@app_product.route("/api/product/update",methods=['POST'])
def product_update():# 按返回模版格式进行json结果返回resp_data = {"code": 20000,"message": "success","data": []}# 获取请求传递jsonbody = request.get_data()body = json.loads(body)# 初始化数据库链接connection = connectDB()with connection:with connection.cursor() as cursor:# 查询需要过滤状态为有效的select = "SELECT * FROM `products` WHERE `keyCode`=%s AND `status`=0"cursor.execute(select, (body["keyCode"],))result = cursor.fetchall()# 有数据并且不等于本身则为重复,封装提示直接返回if len(result) > 0 and result[0]["id"] != body["id"]:resp_data["code"] = 20001resp_data["message"] = "唯一编码keyCode已存在"return resp_data# 如果没有重复,定义新的链接,进行更新操作with connection.cursor() as cursor:# 拼接更新语句,并用参数化%s构造防止基本的SQL注入# 条件为id,更新时间用数据库NOW()获取当前时间sql = "UPDATE `products` SET `keyCode`=%s, `title`=%s,`desc`=%s,`operator`=%s, `update`= NOW() WHERE id=%s"cursor.execute(sql, (body["keyCode"], body["title"], body["desc"], body["operator"], body['id']))# 提交执行保存更新数据connection.commit()return resp_data

修改逻辑中也需要对KeyCode做重复校验,如果需求上定义KeyCode不可以修改,那么只需要前端在修改的时候处理成置灰不可更改就行。另外查询的时候拿去数据我用了是fetchall()做的循环判定,这里可以简化为fetchone() ,毕竟在插入的时候已经做了防重限制,正常情况下只会出现空或一条数据。

同样进行代码逻辑的测试,这里首先演示上说的没做参数校验是啥情况的返回,明显的代码错误在body[“id”]获取的时候异常,直接返回了框架Traceback 错误。

image.png此处是独立的更新接口,因为id是修改操作where关键,笔者是推荐先做一步id参数是否为空的校验,如果是你应该怎么优化呢?提示可以使用 if ('key' not in body): 做逻辑判断。

对于修改这里只验证下正确修改的情况image.png

2.3 删除接口

对于产品列表的删除操作,可以通过硬删除和软删除来实现,前者就是真正DELETE,后者是对其表增加一个状态字段,标记某状态为删除状态,在查询接口中需要通过条件查询排除此状态。

硬删除接口

按照标准的RefAPI,通过定义methods = delete方法定义请求接口,参数只需要对应数据的id,于此同时因为id是删除的操作唯一条件,所以代码逻辑中有必要增一项非空判断。

# [DELETE方法]根据id实际删除项目信息
@app_product.route("/api/product/delete", methods=['DELETE'])
def product_delete():# 返回的reponseresp_data = {"code": 20000,"message": "success","data": []}# 通过params 获取idID = request.args.get('id')# 做个参数必填校验if ID is None:resp_data["code"] = 20002resp_data["message"] = "请求id参数为空"return resp_data# 重新链接数据库connection = connectDB()with connection.cursor() as cursor:sql = "DELETE from `products` where id=%s"cursor.execute(sql, ID)connection.commit()return resp_data
软删除接口

在通常的业务操作中数据都不是真的删除的,尤其像产品/项目这种会有下游依赖的数据,一般做法都是表数据增加对应的状态字段,用数字或者字符表示状态,所需要做的操作就是“删除”触发的是更新操作,在需求交互上我们叫“停用”更为合适一些,这也就是所谓的软删除,仅标记状态不做实际数据删除。

1)先要对products表增加一个状态字段,执行中执行修改命令,或使用IDE直接添加均可。

alter table products add status int default 0 not null comment '状态有效0,无效1' after `desc`;

2)定义的新/api/product/remove接口名,参考修改和硬删除代码实现软删除接口

# [POST方法]根据id更新状态项目状态,做软删除
@app_product.route("/api/product/remove", methods=['POST'])
def product_remove():# 返回的reponseresp_data = {"code": 20000,"message": "success","data": []}ID = request.args.get('id')# 做个参数必填校验if ID is None:resp_data["code"] = 20002resp_data["message"] = "请求id参数为空"return resp_data# 重新链接数据库connection = connectDB()# 更改操作with connection.cursor() as cursor:# 状态默认正常状态为0,删除状态为1# alter table products add status int default 0 not null comment '状态有效0,无效0' after `desc`;sql = "UPDATE `products` SET `status`=1 WHERE id=%s"cursor.execute(sql, ID)connection.commit()return resp_data

以上两个接口就不做测试演示了,大家自行做下验证测试。

3.Python with语句

扩展了解一个python知识点,从上边的所有代码中可以看到,通篇数据操作的没有进行db.close()操作,而是用了with as ,它的基本思想是with所求值对象必须有一个enter()方法,一个exit()方法。应用到数据库操作实例中就是实现了执行退出后关闭具柄,python最常见用语文件处理,举个对比实例:

# 带有异常捕获文件打开和关闭
file = open("/source/qitest.txt")
try:data = file.read()
finally:file.close()   

可优化为如下优雅代码,它帮助我们处理了异常和忘记关闭文件流两种情况

with open("/source/qitest.txt") as file:data = file.read()

以上内容通过串联前几篇的知识内容,实现了产品管理的 接口,并且都是通过数据的方式存储值,下一篇讲基础后端服务接口实现其产品管理的基础交互,你将学到很多新的组件。

最后大奇再啰嗦一句给个建议,文章中给出的大量源代码,希望如果你还是处于语言学习基础阶段,实战的代码最好只是作为参考,真正的要自己一行行敲出来,不要直接拷贝,否则你不会记住多少,也不会遇到问题,更不会锻炼出解决问题的能力。学习的路上方法资料可以参考,但想要有收获是没有捷径的,一起共勉。

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

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

相关文章

VSCode中打开md文件的智能提示

VSCode中打开md文件的智能提示 vscode中md的只能提示是默认关闭的,要打开必须要做些设置. 搜了好多文章,都是坑! 明明没设置成功,参数类型不对还信誓旦旦的坑自己同胞! 也难怪国内人学的那么难,反而国外学的很简单! 找了以下外面的资料,还是隔壁的人认真,给出了以下方法,测试成…

《TCP/IP详解 卷一》第6章 DHCP

目录 6.1 引言 6.2 DHCP 6.2.1 地址池和租用 6.2.2 DHCP和BOOTP消息格式 6.2.3 DHCP和BOOTP选项 6.2.4 DHCP协议操作 6.2.5 DHCPv6 6.2.6 DCHP中继 6.2.7 DHCP认证 6.2.8 重新配置扩展 6.2.9 快速确认 6.2.10 位置信息(LCI和LoST) 6.2.11 移…

OpenCV 4基础篇| OpenCV像素的编辑

目录 1. 前言1. 像素的访问1.1 数组索引访问1.2 img.item() 2. 像素的修改2.1 数值索引修改2.2 img.itemset() 1. 前言 像素是构成数字图像的基本单位,像素处理是图像处理的基本操作。 对像素的访问、修改,可以使用 Numpy 方法直接访问数组元素。 1. 像…

备考2024年AMC10:2000-2023年1250道AMC10真题练一练

我整理了2000-2023年的全部AMC10的AB卷真题共1250题,并且独家制作了多种在线练习,利用碎片化时间,一年足以通过自学在2024年AMC10竞赛中取得好成绩。 我们今天继续来随机看五道题目和解析。 2000-2023年AMC10真题练一练:2013年第…

洛谷P8627 [蓝桥杯 2015 省 A] 饮料换购

#先看题目 题目描述 乐羊羊饮料厂正在举办一次促销优惠活动。乐羊羊 C 型饮料,凭 3 个瓶盖可以再换一瓶 C 型饮料,并且可以一直循环下去(但不允许暂借或赊账)。 请你计算一下,如果小明不浪费瓶盖,尽量地参加活动,那…

Python入门学习——基础语法

一、Python解释器 1. Python解释器的作用是&#xff1a; 将Python代码翻译成计算机认识的O和1并提交计算机执行在解释器环境内可以一行行的执行我们输入的代码也可以使用解释器程序&#xff0c;去执行".py"代码文件 2. Python解释器程序在&#xff1a; <Python…

【第七天】C++模板探秘:函数模板、类模板以及类型转换的深入解析

一、模板的概述 c面向对象编程思想&#xff1a;封装、继承、多态 c泛型编程思想&#xff1a;模板 模板的分类&#xff1a;函数模板、类模板 函数模板&#xff08;类模板&#xff09;&#xff1a;将功能相同&#xff0c;类型不同的函数&#xff08;类&#xff09;的类型抽象成虚…

QoS 服务质量

服务质量 QoS (Quality of Service) 服务质量可用若干基本性能指标来描述&#xff0c;包括&#xff1a;可用性、差错率、响应时间、吞吐量、分组丢失率、连接建立时间、故障检测和改正时间等。 服务提供者可向其用户保证某一种等级的服务质量。 服务性能的总效果&#xff0c;…

svn客户端下载、安装、使用

下载、使用 打开360软件管家&#xff0c;选怎宝库&#xff0c;搜索svn&#xff0c;点击安装 可以修改安装路径 使用 在桌面右键弹出菜单&#xff0c;点击 输入地址&#xff0c;点击ok 输入用户名、密码 &#xff0c;等待检出完成

手把手教你安装和激活Fl Studio21.2.3.4004破解补丁(附激活教程)

盼望着盼望着&#xff0c;FL Studio21带这它的版本号2.3.4004来了&#xff0c;是最新版Fl Studio21.2.3.4004 关于FL Studio21.2.3.4004破解激活&#xff0c;跟之前版本一样&#xff0c;这篇文章将给大家带来FL Studio 21.2.3.400彻底激活教程&#xff0c;喜欢的朋友欢迎一键3连…

第八篇【传奇开心果系列】python的文本和语音相互转换库技术点案例示例:Google Text-to-Speech虚拟现实(VR)沉浸式体验经典案例

传奇开心果博文系列 系列博文目录python的文本和语音相互转换库技术点案例示例系列 博文目录前言一、雏形示例代码二、扩展思路介绍三、虚拟导游示例代码四、交互式学习示例代码五、虚拟角色对话示例代码六、辅助用户界面示例代码七、实时语音交互示例代码八、多语言支持示例代…

守护进程出现拉起多个子进程问题

引言 在我自己开发的httpApi进程中&#xff0c;使用了守护进程&#xff0c;保证进程在意外退出的时候可以重新自动启动。但是使用pstree的时候发现创建了不止一个进程&#xff0c;其中代码和问题现象如下&#xff1a; 代码 int main(int argc, char *argv[]) {printMainVer()…

计算机网络-网络层,运输层,应用层

网络层/网际层 网络层的主要任务包括&#xff1a; 提供逻辑上的端到端通信&#xff1a;网络层负责确定数据的传输路径&#xff0c;使数据能够从源主机传输到目标主机&#xff0c;即实现端到端的通信。数据包的路由和转发&#xff1a;网络层根据目标主机的地址信息&#xff0c…

MySQL事务(基础入门)(高频考点)

文章目录 前言什么是事务&#xff1f;事务的特性并发情况下会出现哪些问题脏读不可重复读幻读 总结 前言 今天来讲一讲 MySQL 事务的基础入门。 更多关于MySQL的知识可以看此专栏 MySQL专栏&#xff08;持续更新&#xff09; 什么是事务&#xff1f; 当我们在操作数据库的时…

深入探索Linux:ACL权限、特殊位与隐藏属性的奥秘

前言&#xff1a; 在Linux系统中&#xff0c;文件和目录的权限管理是一项至关重要的任务。它决定了哪些用户或用户组可以对文件或目录执行读、写或执行等操作。传统的Linux权限模型基于用户、组和其他的概念&#xff0c;但随着时间的推移&#xff0c;这种模型在某些情况下显得…

​​​​​​​Sora:OpenAI的革命性AI视频模型与其对未来影像创作的影响

随着深度学习技术和计算能力的进步&#xff0c;人工智能不仅在图像识别、自然语言处理等领域取得了卓越成就&#xff0c;同时也在不断突破视频处理和生成的边界。在这一背景下&#xff0c;OpenAI推出了Sora——一种新型的AI视频模型&#xff0c;标志着AI在视频内容创作领域的又…

高并发Server的基石:reactor反应堆模式

业务开发同学只关心业务处理流程。但是我们开发的程序都是运行服务端server上&#xff0c;服务端server接收到IO请求后&#xff0c;是如何处理请求并最终进入业务流程的呢&#xff1f;这里不得不提到reactor反应堆模型。nginx tomcat redis nodejs dubbo等软件的网络处理模型都…

snmp协议开通教程

目录 一、什么是snmp协议&#xff1f; 二、snmp协议可以用来干什么&#xff1f; 三、snmp协议的开通 1、snmpv2协议开通 2、snmpv3协议开通 一、什么是snmp协议&#xff1f; SNMP&#xff08;Simple Network Management Protocol&#xff09;是一种用于网络管理的标准协议&a…

LDR6328 PD诱骗芯片:优化小家电Type-C接口充电体验与安全性的关键技术

随着科技的日新月异&#xff0c;小家电设备日趋智能化&#xff0c;Type-C接口因其便捷性在小家电领域的应用也日益增多。然而&#xff0c;Type-C接口的多样性导致设备在识别和使用不同充电方式时面临挑战。为应对这一问题&#xff0c;PD诱骗芯片应运而生&#xff0c;成为解决充…

ONLYOFFICE8.0——赋能办公

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-xdAoM2pHRmDFP0tF {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…