转载至:https://mp.weixin.qq.com/s/x7aJTJ-j1MINc4ZV_quSXQ
在《自动化测试~python数据库设计》中,我们用了两种方式,实现python对数据库的操作
第二种只是在第一种实现方式的基础上,结合上下文管理器对数据库实现了自动连接和关闭的操作
但是不管是上面哪一种,我们频繁的连接、关闭,肯定对性能也是很大的一笔开销
那如何规避上面的问题呢?数据库连接池这个时候就可以用上派场了
数据库连接池的优点:
避免频繁创建、释放连接引起的大量性能开销
由于可以使用现有连接,所以大大缩短了整体的响应时间
设置连接池最大连接数,保护系统资源合理分配
根据预先设定的连接超时,回收占用连接,避免数据库连接引操作引发的资源泄漏
下载依赖包
pip3 install DBUtils
2. 实现demo
'''
@公众号 : 芦荟全栈测开
@File : mysqlpool.py
@Software: PyCharm
'''
import pymysql
from dbutils.pooled_db import PooledDB
import logging
class MySqlManage:
"数据库操作"
def __init__(self, **kwargs):
#数据库连接对象
self.dbPool = PooledDB(
creator=pymysql,
maxconnections=8,
mincached=2,
blocking=True,
host=kwargs["host"],
port=kwargs["port"],
user=kwargs["username"],
password=kwargs["passwd"],
database=kwargs["database"],
charset="utf8"
)
#连接
self.conn = self.dbPool.connection()
# 游标
self.cursor = self.conn.cursor()
def selectAll(self, sql):
"""
查询所有
:param sql: sql语句
:return: 返回查询结果(元祖)
"""
try:
self.cursor.execute(sql)
result = self.cursor.fetchall()
except Exception as e:
logging.error(f"数据库查询失败->{e}-{sql}")
else:
return result
def selectOne(self, sql):
"""
查询单挑数据
:param sql:
:return: 返回查询结果(元祖)
"""
try:
self.cursor.execute(sql)
result = self.cursor.fetchone()
except Exception as e:
logging.error(f"数据库单挑查询失败->{e}->{sql}")
else:
return result
def insertSql(self, sql):
"""
数据库插入
:param sql:
:return:
"""
try:
self.cursor.execute(sql)
self.conn.commit()
except Exception as e:
self.conn.rollback()
logging.error(f"数据库插入失败->{e}->{sql}")
def updataDb(self, sql):
"""
数据库更新
:param sql: 更新数据库sql语句
:return:
"""
self.cursor = self.conn.cursor(pymysql.cursors.DictCursor)
try:
self.cursor.execute(sql)
self.conn.commit()
except Exception as e:
self.conn.rollback()
logging.error("数据库更新数据出现异常,异常报错信息:{}".format(e))
3. 调用
conInfo = {
"host": "localhost",
"port": 3306,
"username": "root",
"passwd": "root",
"database": "mysql"
}
sql = "SELECT * FROM USER;"
result = MySqlManage(**conInfo).selectAll(sql)
PooledDB(xx=xxx)常用参数介绍
creator=pymysql # 使用链接数据库的模块
maxconnections=6 # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2 # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5 # 链接池中最多闲置的链接,0和None不限制
maxshared=3 # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None # 一个链接最多被重复使用的次数,None表示无限制
setsession=[] # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0 # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
就像我们并发执行自动化case的时候,一定要注意数据安全问题,一般涉及到数据安全性问题就会涉及到锁,涉及到锁以及我们上面说的连接数的大小设置,都会影响到性能,就比如,若是连接数设定的太小,就会造成队列等待,若是连接数设定的太大,则造成资源浪费,这些都会影响性能,当然我们会在性能分析中结合项目做详细讲解。