引言
在进行功能或者接口测试时常常需要通过连接数据库,操作和查看相关的数据表数据,用于构建测试数据、核对功能、验证数据一致性,接口的数据库操作是否正确等。因此,在进行接口自动化测试时,我们一样绕不开接口和数据库的交互,我们需要用代码连接数据库,通过操作数据库完成数据的准备、环境检查以及数据库断言的功能。在python3中,使用python操作MySQL数据库需要使用到第三方库:pymysql,该模块本质上就是一个套接字的客户端软件包,它提供了诸多连接数据库、操作数据库表等一系列的方法。
一、PyMySQL安装
1.在windows环境下安装
由于python3.6及以上版本安装python后就自带了pip3,python版本低于3.6的,手动安装下pip即可,因此可以直接使用pip安装该模块
pip3 install pymysql
2.在linux环境下安装
下载安装pymysql的tar包,解压后,进入解压的目录下,按如下安装即可:
[root@localhost opt]#tar -xzvf PyMySQL-0.7.11.tar.gz [root@localhost opt]#cd PyMySQL-0.7.11 [root@localhost PyMySQL-0.7.11]#python36 setup.py install
3.在PyCharm中安装
在PyCharm中直接检索该模块,并安装,步骤如下:
二、Python操作数据库
因为方便测试,我们首先在mysql数据库创建测试表:userinfo,表信息如下:
有了数据库和数据表后,我们就可以导入pymysql模块,使用该模块下封装的方法实现数据库操作
数据库连接
pymysql提供的方法如下:
1. 建立数据库连接 conn = pymysql.connect()
2. 从连接建立操作游标 cur = conn.cursor()
3. 使用游标执行sql(读/写) cur.execute(sql)
4. 获取结果(读)/ 提交更改(写) cur.fetchall() / conn.commit()
5. 关闭游标及连接 cur.close();conn.close()
代码示例:
import pymysql # 建立连接 connection = pymysql.connect(host=\'119.29.78.234\', port=3306, user=\'root\', password=\'dhcc@2020\', db=\'test123\') cursor = connection.cursor() # 创建游标 cursor.execute("SELECT * FROM userinfo") #使用execute()方法执行SQL语句 data = cursor.fetchall() #使用fetall()获取全部数据 print(data) cursor.close() #关闭游标和数据库的连接 connection.close()
#运行结果
((1, \'艾佛森\', \'123\'), (2, \'科比\', \'123\'), (3, \'詹姆斯\', \'123\'), (4, \'库里\', \'123\'))
什么是游标? 游标类似文件句柄,可以逐条的访问数据库执行结果集。pymysql中只能通过游标来执行sql和获取结果
以上代码执行后,默认返回的是一个嵌套元组数据类型
数据库增删改查
查询操作:
使用cur.execute(), 执行数据库查询后无返回的是影响的行数,而非查询结果。我们要使用cur.fetchone()/cur.fetchmany()/cur.fetchall()来获取查询结果
cur.fetchone(): 获取一条数据(同时获取的数据会从结果集删除),返回元组
cur.fetchmany(3): 获取多条数据,返回嵌套元组
cur.fetchall(): 获取所有数据,返回嵌套元组
代码示例:
查询单条数据:
import pymysql db_config = { "host":"119.29.78.234", "port":3306, "user":"root", "password":"dhcc@2020", "db":"test123" } db = pymysql.connect(**db_config) cursor = db.cursor() sql = "SELECT * FROM userinfo" cursor.execute(sql) res = cursor.fetchone() # fetchone()第一次只能查询表中的首行数据 print(res) res = cursor.fetchone() # 第二次查询下一行数据 print(res) cursor.close() db.close()
# 返回结果
((1, \'艾佛森\', \'123\'))
((2, \'科比\', \'123\'))
查询多条数据:
import pymysql db_config = { "host":"119.29.78.234", "port":3306, "user":"root", "password":"dhcc@2020", "db":"test123" } db = pymysql.connect(**db_config) cursor = db.cursor() sql = "SELECT * FROM userinfo" cursor.execute(sql) res = cursor.fetchmany(3) # 第一次查询表中的前3行数据 print(res) res = cursor.fetchmany(3) # 第二次查询下一个3行的数据 print(res) cursor.close() db.close()
#返回结果 ((1, \'艾佛森\', \'123\'), (2, \'科比\', \'123\'), (3, \'詹姆斯\', \'123\')) ((4, \'库里\', \'123\'),)
查询所有数据:
import pymysql db_config = { "host":"119.29.78.234", "port":3306, "user":"root", "password":"dhcc@2020", "db":"test123" } db = pymysql.connect(**db_config) cursor = db.cursor() sql = "SELECT * FROM userinfo" cursor.execute(sql) res = cursor.fetchall() # 第一次查询表中的所有数据 print(res) res = cursor.fetchall() # 第二次查询无数据 print(res) cursor.close() db.close()
#返回结果 ((1, \'艾佛森\', \'123\'), (2, \'科比\', \'123\'), (3, \'詹姆斯\', \'123\'), (4, \'库里\', \'123\')) ()
默认都是返回元组的数据类型,看起来不太直观,因此,在实例化时可以将游标设置成如下这样,就可以返回字典类型的数据
cursor = db.cursor(cursor=pymysql.cursors.DictCursor)
#返回结果
[{\'username\': \'艾佛森\', \'id\': 1, \'passwd\': \'123\'}, {\'username\': \'科比\', \'id\': 2, \'passwd\': \'123\'}, {\'username\': \'詹姆斯\', \'id\': 3, \'passwd\': \'123\'}, {\'username\': \'库里\', \'id\': 4, \'passwd\': \'123\'}]
增删改操作:
在进行增删改,执行修改数据库的操作后不立即生效,使用连接conn.commit()提交后才生效,支持事物及回滚
代码示例:
import pymysql db_config = { "host":"119.29.78.234", "port":3306, "user":"root", "password":"dhcc@2020", "db":"test123" } db = pymysql.connect(**db_config) cursor = db.cursor() sql = "INSERT INTO userinfo(username,passwd) VALUES(\'克莱\',\'123\')" #sql = "UPDATE userinfo SET username = \'奥尼尔\' WHERE username = \'科比\'" # 修改数据 #sql = "DELETE FROM username WHERE username =\'奥尼尔\'" # 删除数据 try: cursor.execute(sql) db.commit() except Exception as e : # 执行异常回滚 db.rollback() cursor.close() db.close() #或者在execute提供需要插入的数据 import pymysql db_config = { "host":"119.29.78.234", "port":3306, "user":"root", "password":"dhcc@2020", "db":"test123" } db = pymysql.connect(**db_config) cursor = db.cursor() sql = "INSERT INTO userinfo(username,passwd) VALUES(%s,%s)" try: cursor.execute(sql,("克莱","123")) db.commit() except Exception as e : db.rollback() cursor.close() db.close() #批量插入数据 import pymysql db_config = { "host":"119.29.78.234", "port":3306, "user":"root", "password":"dhcc@2020", "db":"test123" } db = pymysql.connect(**db_config) cursor = db.cursor() sql = "INSERT INTO userinfo(username,passwd) VALUES(%s,%s)" try: cursor.executemany(sql,[("韦德","123"),("字母哥","123")]) db.commit() except Exception as e : db.rollback() cursor.close() db.close()
封装数据库操作
由于经常要使用到数据库操作,建议将所有数据库操作封装成公用的数据库模块
封装的代码示例如下:
import pymysql.cursors class Operation_mysql(object): def __init__(self): # 建立连接 db_config = { "host": "119.29.78.234", "port": 3306, "user": "root", "password": "dhcc@2020", "db": "test123" } self.connection = pymysql.connect(**db_config) # 创建游标 self.cursor = self.connection.cursor() def execute_sql(self, sql): try: self.cursor.execute(sql) self.connection.commit() except Exception as e: # 执行异常回滚 db.rollback() def get_data(self): data = self.cursor.fetchone() #data = self.cursor.fetchall() # 查询所有数据 return data def close_mysql(self): # 关闭游标 self.cursor.close() # 关闭数据库连接 self.connection.close()
这样封装后后续接口测试用例需要操作数据库时,就可以引入该模块,实例化对象调用该模块下的方法。