【测试平台开发】——06Flask后端api开发实战(三)——API接口关联数据库
本章节演示如何创建接口服务,用接口关联数据库数据,包括get请求和post请求。
一、Flask-RESTful插件
restful api是用于在前端与后台进行通信的一套规范。使用这个规范可以让前后端开发变得更加轻松。以下将讨论这套规范的一些设计细节。
英文地址:https://flask-restful.readthedocs.io/en/latest/
中文地址:http://www.pythondoc.com/Flask-RESTful/index.html
安装命令:
pip install flask-restful
上代码,红色字体为使用插架用法:
from flask import Flask
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def __repr__(self):
return f'<User {self.username} {self.email}>' # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
return {'hello': 'get'} def post(self):
return {'hello': 'post'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/') if __name__ == '__main__':
# db.drop_all()
# db.create_all()
#
#
# for i in range(30):
# data = TestCase(nodeid=f'nodeid_{i+1}', description=f'备注{i+1}')
# db.session.add(data)
# db.session.commit() app.run(debug=True)
1、GET请求
在浏览器中输入地址:http://127.0.0.1:5000/

2、POST请求
>>> import requests
>>> r = requests.post("http://127.0.0.1:5000")
>>> r.text '{\n "hello": "post"\n}\n'
二、接口查询数据(GET)
使用GET接口查询数据
from flask import Flask
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases def post(self):
return {'hello': 'post'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase') if __name__ == '__main__': app.run(debug=True)

三、接口新增数据(POST)
1、首先验证使用post接口接收数据
# 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases def post(self):
"""
新增用例
:return:
"""
nodeid = request.json.get("nodeid")
description = request.json.get("description")
return [nodeid, description] # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase')
Python Console输入post请求:
>>> import requests
>>> r = requests.post("http://127.0.0.1:5000/testcase", json={"nodeid": '999', "description": '999感冒灵'})
>>> r.text '[\n "999",\n "999\\u611f\\u5192\\u7075"\n]\n'
这个例子介绍post接口如何接收数据。
2、post接口结合数据库进行关联(※重点)
from flask import Flask, request
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases def post(self):
"""
新增用例
:return:
"""
# 把消息体中的数据,发送到数据库中
data = TestCase(**request.json)
db.session.add(data)
db.session.commit()
return {'msg': 'OK'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase') if __name__ == '__main__': app.run(debug=True)
Python Console输入post请求:
>>> r = requests.post("http://127.0.0.1:5000/testcase", json={"nodeid": '999', "description": '999感冒灵'})
>>> r.text
# 结果
'{\n "msg": "OK"\n}\n'
数据库新增数据:

四、接口删除数据(GET)
1、首先验证使用post接口接收数据
# 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
(二)删除测试用例数据
:return:
"""
option = request.args.get("option")
if option == 'get_testcase':
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases
# 如果url中option参数值为del_testcase,代表删除用例
elif option == 'del_testcase':
nodeid = request.args.get("nodeid")
return nodeid
浏览器输入:http://127.0.0.1:5000/testcase?option=del_testcase&nodeid=1234

2、可以通过get接口接收数据,下一步关联数据库(※重点)
from flask import Flask, request
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
(二)删除测试用例数据
:return:
"""
option = request.args.get("option")
if option == 'get_testcase':
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases
# 如果url中option参数值为del_testcase,代表删除用例
elif option == 'del_testcase':
nodeid = request.args.get("nodeid")
# 查询用例后进行删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
db.session.commit()
return {'msg': 'delete is ok!'}
except:
return {'msg': 'delete is error!'} def post(self):
"""
新增用例
:return:
"""
data = TestCase(**request.json)
db.session.add(data)
db.session.commit()
return {'msg': 'OK'} # 添加到flask-restful中,并增加路由
api.add_resource(TestCaseServer, '/testcase') if __name__ == '__main__': app.run(debug=True)

浏览器输入地址:http://127.0.0.1:5000/testcase?option=del_testcase&nodeid=999

数据库删除了这条数据!

3、接口批量删除数据
# 定义测试用例接口
class TestCaseServer(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
(二)删除测试用例数据
:return:
"""
option = request.args.get("option")
if option == 'get_testcase':
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases
# 如果url中option参数值为del_testcase,代表删除用例
elif option == 'del_testcase':
nodeid = request.args.get("nodeid")
# 查询用例后进行删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
db.session.commit()
return {'msg': 'delete is ok!'}
except:
return {'msg': 'delete is error!'}
elif option == 'del_testcases':
nodeids = request.args.get("nodeids")
for nodeid in nodeids.split(','):
# 查询用例后进行批量删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
except:
return {'msg': 'delete is error!'}
db.session.commit()
return {'msg': 'delete is ok!'} api.add_resource(TestCaseServer, '/testcase')
if __name__ == '__main__':
app.run(debug=True)
浏览器输入:http://127.0.0.1:5000/testcase?option=del_testcases&nodeids=888,999

删除前:

删除后:

五、接口更新数据——API接口Url分开
为什么要分开写呢,因为如果项目足够大,不能只用一个Url写各种各样的接口,需要我们把Url区分一下,一个接口一个Url。
1、写法一
# 定义测试用例更新接口
class TestCaseUpdate(Resource):
"""更新测试用例"""
def post(self):
nodeid = request.args.get('nodeid')
data = TestCase.query.filter_by(nodeid=nodeid).first()
data.description = '藿香正气水'
db.session.commit()
return {'msg': 'update is success!'} # 添加到flask-restful中,并增加更新路由
api.add_resource(TestCaseUpdate, '/testcase/update')
Python Console输入:
>>> r = requests.post("http://127.0.0.1:5000/testcase/update?nodeid=999")
>>> r.text
# 结果
'{\n "msg": "update is success!"\n}\n'

2、写法二(推荐※)
# 定义测试用例更新接口
class TestCaseUpdate(Resource):
"""更新测试用例"""
def post(self):
request_body = request.json
data = TestCase.query.filter_by(nodeid=request_body.get('nodeid')).first()
data.description = request_body.get('description')
db.session.commit()
return {'msg': 'update is success!'} # 添加到flask-restful中,并增加更新路由
api.add_resource(TestCaseUpdate, '/testcase/update')
Python Console输入:
>>> r = requests.post("http://127.0.0.1:5000/testcase/update", json={'nodeid': 999, "description": '999感冒灵'})
>>> r.text
# 结果
'{\n "msg": "update is success!"\n}\n'

六、整合所有API接口(重点※※※※※)
对于以上接口,全部采取Url分开的写法进行整合:
from flask import Flask, request
from flask_restful import Resource, Api
from flask_sqlalchemy import SQLAlchemy app = Flask(__name__)
# 配置数据库详细信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:1234567@localhost:8881/2022.8.3Data'
# 初始化一个db
db = SQLAlchemy(app)
# 将flask实例加载到flask-restful
api = Api(app) class TestCase(db.Model):
id = db.Column(db.Integer, primary_key=True)
nodeid = db.Column(db.String(80), unique=True, nullable=False)
description = db.Column(db.String(120), unique=False, nullable=True) def as_dict(self):
"""
返回测试用例的数据
:return:
"""
return {"id": self.id, "nodeid": self.nodeid, "description": self.description} # 定义测试用例新增接口
class TestCaseAdd(Resource):
def post(self):
"""
新增用例
:return:
"""
data = TestCase(**request.json)
db.session.add(data)
db.session.commit()
return {'msg': 'Add is OK!'} # 定义测试用例删除接口
class TestCaseDelete(Resource):
# get方法代表接收get请求
def get(self):
"""
删除测试用例数据
:return:
"""
if "nodeid" in request.args:
nodeid = request.args.get("nodeid")
# 查询用例后进行删除
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
db.session.commit()
return {'msg': 'delete is ok!'}
except:
return {'msg': 'delete is error!'}
elif "nodeids" in request.args:
nodeids = request.args.get("nodeids")
print(nodeids)
# 查询用例后进行批量删除
for nodeid in nodeids.split(','):
data = TestCase.query.filter_by(nodeid=nodeid).first()
try:
db.session.delete(data)
except:
return {'msg': 'delete is error!'}
db.session.commit()
return {'msg': 'delete is ok!'} # 定义测试用例更新接口
class TestCaseUpdate(Resource):
"""更新测试用例"""
def post(self):
request_body = request.json
data = TestCase.query.filter_by(nodeid=request_body.get('nodeid')).first()
data.description = request_body.get('description')
db.session.commit()
return {'msg': 'update is success!'} # 定义测试用例查询接口
class TestCaseSearch(Resource):
# get方法代表接收get请求
def get(self):
"""
(一)获取所有测试用例数据
:return:
"""
# 1、查找所有测试用例数据
testcase = TestCase.query.all()
# 2、对测试用例进行实例化
format_test_cases = [i.as_dict() for i in testcase]
return format_test_cases # 添加到flask-restful中,并增加新增路由
api.add_resource(TestCaseAdd, '/testcase/add')
# 添加到flask-restful中,并增加删除路由
api.add_resource(TestCaseDelete, '/testcase/delete')
# 添加到flask-restful中,并增加更新路由
api.add_resource(TestCaseUpdate, '/testcase/update')
# 添加到flask-restful中,并增加查询路由
api.add_resource(TestCaseSearch, '/testcase/search') if __name__ == '__main__':
# db.drop_all()
# db.create_all()
#
#
# for i in range(30):
# data = TestCase(nodeid=f'nodeid_{i+1}', description=f'备注{i+1}')
# db.session.add(data)
# db.session.commit() app.run(debug=True)
七、说明一下接口类型
参考文章:感谢故屿γ的《Get、Put、Post、Delete 含义与区别》
1、GET 请求会向数据库发索取数据的请求,从而来获取信息,该请求就像数据库的 select 操作一样,只是用来查询一下数据,不会修改、增加数据,不会影响资源的内容,即该请求不会产生副作用。无论进行多少次操作,结果都是一样的。 2、PUT 请求是向服务器端发送数据的(与 GET 不同)从而改变信息,该请求就像数据库的 update 操作一样,用来修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次 PUT 操作,其结果并没有不同。 3、POST 请求同 PUT 请求类似,都是向服务器端发送数据的,但是该请求会改变数据的种类等资源,就像数据库的 insert 操作一样,会创建新的内容。几乎目前所有的提交操作都是用 POST 请求的。 4、DELETE 请求顾名思义,就是用来删除某一个资源的,该请求就像数据库的 delete 操作。
就像前面所讲的一样,既然 PUT 和 POST 操作都是向服务器端发送数据的,那么两者有什么区别呢? POST 主要作用在一个集合资源之上的(url),而 PUT 主要作用在一个具体资源之上的(url/xxx),通俗一下讲就是,如 URL 可以在客户端确定,那么可使用 PUT,否则用 POST。
总结一下,Get 是向服务器发索取数据的一种请求,而 Post 是向服务器提交数据的一种请求,在 FORM(表单)中,Method默认为 “GET”,实质上,GET 和 POST 只是发送机制不同,并不是一个取一个发。
基于上面的代码,总结一下接口类型使用:
POST /url/add 新增 POST /url/update 更新 GET /url/delete 删除 GET /url/search 查询
八、自动化平台系列文章汇总
【测试平台开发】——06Flask后端api开发实战(三)——API接口关联数据库的更多相关文章
- teprunner测试平台用例前置模块开发
本文开发内容 现在正式进入测试相关功能开发.teprunner测试平台底层是pytest,中间层是tep,还没了解的朋友可以先看看tep的文章,整个平台的设计思路和后面用例的执行都会基于这个工具.te ...
- django 开发之前后端分离开发模式
1. 什么是前后端分离开发的概念: 前端页面运行前端服务器上,负责页面的渲染(静态文件的加载)与跳转 后端代码运行在后端服务器上, 负责数据的处理(提供数据请求的接口) 2. 前后端分离开发碰到的问题 ...
- java开发-前后端分离
众所周知,做java开发是后端的开发,我们时常与前端打交道,但更加注重后端代码的实现,前台的页面都是由前端开发人员做的,那么,是怎么做到前后端分离的呢? 首先,是后端的开发, 在mapper层:Stu ...
- java EE技术体系——CLF平台API开发注意事项(1)——后端开发
前言:这是一篇帮助小伙伴在本次项目中快速进入到java EE开发的一些说明,为了让同组小伙伴们开发的时候,有个清晰点的思路.昨天给大家演示分享了基本概况,但没有留下文字总结说明,预防后期有人再次问我, ...
- 前后端分离开发,基于SpringMVC符合Restful API风格Maven项目实战(附完整Demo)!
摘要: 本人在前辈<从MVC到前后端分离(REST-个人也认为是目前比较流行和比较好的方式)>一文的基础上,实现了一个基于Spring的符合REST风格的完整Demo,具有MVC分层结构并 ...
- java EE技术体系——CLF平台API开发注意事项(4)——API生命周期治理简单说明
文档说明 截止日期:20170905,作者:何红霞,联系方式:QQ1028335395.邮箱:hehongxia626@163.com 综述 有幸加入到javaEE技术体系的研究与开发,也得益于大家的 ...
- [转] 前后端分离开发模式的 mock 平台预研
引入 mock(模拟): 是在项目测试中,对项目外部或不容易获取的对象/接口,用一个虚拟的对象/接口来模拟,以便测试. 背景 前后端分离 前后端仅仅通过异步接口(AJAX/JSONP)来编程 前后端都 ...
- 学习版pytest内核测试平台开发万字长文入门篇
前言 2021年,测试平台如雨后春笋般冒了出来,我就是其中一员,写了一款pytest内核测试平台,在公司落地.分享出来后,有同学觉得挺不错,希望能开源,本着"公司代码不要传到网上去,以免引起 ...
- 测试开发【提测平台】分享3-正式开发产品需求&项目初始化
上两个分享主要是介绍和演示基本前后端所要使用的框架,接下来我们将正式进入到[提测平台的开发] 提要先给出依赖和内容点: 提测平台定义和产品原型需求说明 使用github创建代码仓库进行项目管理 Fla ...
- 超越村后端开发(4:API开发)
1.users相关的api开发 1.在settings中添加APPID,SECRET 2.在apps/users/views.py内: from chaoyuecun.settings import ...
随机推荐
- Java 方法中循环调用具有事务的方法
在Java中,循环调用一个具有事务的方法时,需要特别注意事务的边界和管理.通常,事务的边界是由框架(如Spring)来控制的,确保方法执行时数据的完整性和一致性.然而,在循环中调用事务方法时,每个调用 ...
- Spring手动获取bean的四种方式
一.实现BeanFactoryPostProcessor接口 @Component public class SpringUtil implements BeanFactoryPostProcesso ...
- PO、VO、BO、DTO、POJO、DAO、DO
DO: domain object持久对象就是从现实世界中抽象出来的有形或无形的业务实体. PO:persistant object持久对象最形象的理解就是一个PO就是数据库中的一条记录.好处是可以把 ...
- Vue 数组和对象更新,但视图未更新,背后的故事
在实际开发中,遇到遍历数组和对象,当property 发生改变时,并没有触发视图的更新今天来浅显的聊聊这背后的故事,有说的不对地方,还望指出! 本人博文地址:https://www.cnblogs.c ...
- CF369D Valera and Fools 题解
题目链接 Luogu Codeforces 题意简述 有 \(n\) 个人站成一排,每人手中有 \(k\) 发子弹,每次每人会向除自己外编号最小的人开枪,第 \(i\) 个人开枪的命中率为 \(p_i ...
- ASP.NET Core 程序集注入(二)
public void ConfigureServices(IServiceCollection services) { string strValue = Configuration.GetSect ...
- 03-springboot使用单元测试和日志框架
目录 1,springboot使用单元测试 2,使用日志框架 1,springboot使用单元测试 A:springboot使用单元测试需要引入一个单元测试启动器,该启动器的坐标为: <depe ...
- 面试题-python 什么是闭包(closure)?
前言 前面学了装饰器,那么闭包和装饰器有什么区别呢?闭包传递的是变量,而装饰器传递的是函数对象,只是传的参数内容不一样,闭包的概念包含了装饰器,可以说装饰器是闭包的一种,它只是传递函数对象的闭包. 先 ...
- JAVA并发编程理论基础
注:本文章是对极客时间<java并发编程实战>学习归纳总结,更多知识点可到原文 java并发编程实战 进行学习.如果侵权,联系删除: 一.并发编程的BUG的源头 1.1 缓存导致的可见性问 ...
- python面向对象:多态
python面向对象:多态 多态的应用场景 1. 对象所属的类之间没有继承关系 调用同一个函数fly(), 传入不同的参数(对象),可以达成不同的功能 class Duck(object): # 鸭子 ...