Python如何使用数据库的连接池

2023-12-25 20:34:02

Python 数据库连接池

python编程中可以使用pymysql进行数据库连接及增删改查操作,但每次连接mysql请求时,都是独立的去请求访问,比较浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用。

python的数据库连接池包:DBUtils

DBUtils提供两种外部接口:

PersistentDB:提供线程专用的数据库连接,并自动管理连接。

PooledDB:提供线程间可共享的数据库连接,并自动管理连接。?

DBUtils包安装: pip3 install DBUtils或者下载 DBUtils 安装包,解压后,使用python setup.py install 命令进行安装。

未使用连接池的数据库方法:

def?getconn(host,?user,?passwd,?db,?sql,?port=3306,charset='utf8'):
????conn?=?pymysql.connect(host=host,?user=user,?passwd=passwd,?port=port,?db=db,?charset=charset)??#建立连接
????cur?=?conn.cursor(cursor=pymysql.cursors.DictCursor)????????#建立游标并指定游标类型
????cur.execute(sql)??????????????????????????????#执行sql
????if?sql.startswith('select'):????????????????????#判断sql是否是select
????????res?=?cur.fetchone()
????else:
????????conn.commit()???????????????????#insert\delete\update语句执行完毕后需要进行commit
????????res?=?88
????cur.close()????????????????????????#关闭游标
????conn.close()???????????????????????#关闭连接
????return?res

用数据库连接池后的方法:

import?MySQLdb
from?DBUtils.PooledDB?import?PooledDB
pool?=?PooledDB(MySQLdb,5,host='localhost',user='root',passwd='pwd',db='myDB',port=3306)?#5为连接池里的最少连接数
?
conn?=?pool.connection()??#以后每次需要数据库连接就是用connection()函数获取连接就好了
cur=conn.cursor()
SQL="select?*?from?table1"
r=cur.execute(SQL)
r=cur.fetchall()
cur.close()
conn.close()

下面利用pymysql 和 DBUtils 建立自己的mysql数据库连接工具包。

class?OPMysql(object):
????__pool?=?None
????def?__init__(self):
????????#?构造函数,创建数据库连接、游标
????????self.coon?=?OPMysql.getmysqlconn()
????????self.cur?=?self.coon.cursor(cursor=pymysql.cursors.DictCursor)
????#?数据库连接池连接
????@staticmethod
????def?getmysqlconn():
????????if?OPMysql.__pool?is?None:
????????????__pool?=?PooledDB(creator=pymysql,?mincached=1,?maxcached=20,?host=mysqlInfo['host'],?user=mysqlInfo['user'],?passwd=mysqlInfo['passwd'],?db=mysqlInfo['db'],?port=mysqlInfo['port'],?charset=mysqlInfo['charset'])
????????????print(__pool)
????????return?__pool.connection()
????#?插入\更新\删除sql
????def?op_insert(self,?sql):
????????print('op_insert',?sql)
????????insert_num?=?self.cur.execute(sql)
????????print('mysql?sucess?',?insert_num)
????????self.coon.commit()
????????return?insert_num
????#?查询
????def?op_select(self,?sql):
????????print('op_select',?sql)
????????self.cur.execute(sql)??#?执行sql
????????select_res?=?self.cur.fetchone()??#?返回结果为字典
????????print('op_select',?select_res)
????????return?select_res
????#释放资源
????def?dispose(self):
????????self.coon.close()
????????self.cur.close()

配置文件mysqlinfo,包含数据库的连接信息、用户名密码等:

mysqlInfo?=?{
????"host":?'192.168.1.112',
????"user":?'root',
????"passwd":?'123456',
????"db":?'apitest',
????"port":?3306,
????"charset":?'utf8'
}

创建test,测试数据库连接

if?__name__?==?'__main__':
????#申请资源
????opm?=?OPMysql()
????sql?=?"select?*?from?demo?where?name?='a'?and?pwd='e10adc3949ba59abbe56e057f20f883e'?"
????res?=?opm.op_select(sql)
????#释放资源
????opm.dispose()

PooledDB参数解释:

mincached,最少的空闲连接数,如果空闲连接数小于这个数,pool会创建一个新的连接。

maxcached,空闲连接数,如果空闲连接数大于这个数,pool会关闭空闲连接。

maxconnections,连接数,进程中可创建的线程数。

blocking, 当连接数达到连接数时,再次请求时,如果这个值是True,请求连接的程序会一直等待,直到当前连接数小于连接数;如果这个值为False,会报错。

masxshared,当连接数达到这个数时,新请求的连接会分享已经分配出去的连接。

在uwsgi中,每个http请求都会有一个进程,连接池中配置的连接数都是一个进程为单位的(即上面的连接数,都是在一个进程中创建的线程数),如果业务中,一个http请求中需要的sql连接数不是很多的话(其实大多数都只需要创建一个连接),配置的连接数配置都不需要太大。

连接池对性能的提升:

在程序创建连接的时候,可以从一个空闲的连接中获取,不需要重新初始化连接,提升获取连接的速度。

关闭连接的时候,把连接放回连接池,而不是真正的关闭,所以可以减少频繁的打开和关闭连接。

文章来源:https://blog.csdn.net/hakesashou/article/details/135207912
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。