概述
python的数据库连接池较多,这里介绍的是DbUtils
官方文档api:https://cito.github.io/DBUtils/UsersGuide.html
中文翻译:https://blog.csdn.net/zhaihaifei/article/details/53996866
pypi网址:https://pypi.org/project/DBUtils/#description
安装
pip install DBUtils
DbUtils
DBUtils是一套Python数据库连接池包,并允许对非线程安全的数据库接口进行线程安全包装。DBUtils来自Webware for Python。
DBUtils提供两种模式:
- PersistentDB
- PooledDB
这两种模式的区别,在下面的例子中有详细解释。另外,与数据库驱动也有关系,比如SQLite数据库只能使用PersistentDB
重点掌握 PooledDB
导入模块
3.0.3之前导入模块如下:
from DBUtils.PooledDB import PooledDB
3.0.3以后导入模块如下:
from dbutils.pooled_db import PooledDB
PooledDB
# coding=utf-8
from DBUtils.PooledDB import PooledDB
import mysql.connector as connector
pool = PooledDB(
creator = connector, #使用链接数据库的模块
maxconnections = 5, #连接池允许的最大连接数,0和None表示没有限制
mincached = 2, #初始化时,连接池至少创建的空闲的连接,0表示不创建
maxcached = 3, #连接池空闲的最多连接数,0和None表示没有限制
maxshared = 0, #连接池中最多共享的连接数量,0和None表示全部共享,ps:其实并没有什么用,因为pymsql和MySQLDB等模块中的threadsafety都为1,所有值无论设置多少,_maxcahed永远为0,所以永远是所有链接共享
blocking = True, #链接池中如果没有可用共享连接后,是否阻塞等待,True表示等待,False表示不等待然后报错
setsession = [],#开始会话前执行的命令列表
ping = 0,#ping Mysql 服务端,检查服务是否可用
host = '127.0.0.1',
port = 3308,
user = 'root',
password = '',
database = 'test',
charset = 'utf8'
)
# 获取数据库连接的方式
conn = pool.connection()
例子
# coding=utf-8
from DBUtils.PooledDB import PooledDB
import mysql.connector as connector
import dbutil,time
from threading import Timer
conns=[]
def main():
global conns
pool = PooledDB(
creator = connector, #使用链接数据库的模块
maxconnections = 5, #连接池允许的最大连接数,0和None表示没有限制
mincached = 2, #初始化时,连接池至少创建的空闲的连接,0表示不创建
maxcached = 3, #连接池空闲的最多连接数,0和None表示没有限制
maxshared = 0, #连接池中最多共享的连接数量,0和None表示全部共享,ps:其实并没有什么用,因为pymsql和MySQLDB等模块中的threadsafety都为1,所有值无论设置多少,_maxcahed永远为0,所以永远是所有链接共享
blocking = True, #链接池中如果没有可用共享连接后,是否阻塞等待,True表示等待,False表示不等待然后报错
setsession = [],#开始会话前执行的命令列表
ping = 0,#ping Mysql 服务端,检查服务是否可用
host = '127.0.0.1',
port = 3308,
user = 'root',
password = '',
database = 'test',
charset = 'utf8'
)
Timer(3,close).start()
db=dbutil.MySQLUtil()
for item in range(10):
conn = pool.connection()
conns.append(conn)
print(item)
db.connection=conn
data=db.queryone("show status like 'Threads_connected'")
print('数据库总共连接数:',data)
data=db.queryone("SELECT CONNECTION_ID()")
print('当前连接的ID:',data)
time.sleep(50)
def close():
conns[0].close()
conns[1].close()
if __name__ == "__main__":
main()
由于设置了以下参数:
maxconnections = 5, #连接池允许的最大连接数,0和None表示没有限制
mincached = 2, #初始化时,连接池至少创建的空闲的连接,0表示不创建
blocking = True, #链接池中如果没有可用共享连接后,是否阻塞等待,True表示等待,False表示不等待然后报错
从打印结果可知:
- 初始化时,只创建2个数据库连接
- 之后从连接池中获取连接
- 当连接不够用时,继续创建连接
- 当创建5个连接时,就处于等待状态
- 当有连接关闭时,并没有真正的关闭,而是回收到连接池中
- 可以继续从连接池中获取连接,从连接的ID可知,并没有创建新的,而是使用了回收的连接
PersistentDB
# coding=utf-8
from DBUtils.PersistentDB import PersistentDB
import mysql.connector as connector
import dbutil,time
from threading import Timer
pool = PersistentDB(
creator = connector, #使用链接数据库的模块
maxusage = None, #一个链接最多被使用的次数,None表示无限制
setsession = [], #开始会话前执行的命令
ping = 0, #ping MySQL服务端,检查服务是否可用
closeable = False, #conn.close()实际上被忽略,供下次使用,直到线程关闭,自动关闭链接,而等于True时,conn.close()真的被关闭
threadlocal = None, # 本线程独享值的对象,用于保存链接对象
host = '127.0.0.1',
port = 3308,
user = 'root',
password = '',
database = 'test',
charset = 'utf8'
)
#获取数据库连接
conn = pool.connection()
例子
# coding=utf-8
from DBUtils.PersistentDB import PersistentDB
import mysql.connector as connector
import dbutil,time
from threading import Timer
pool = PersistentDB(
creator = connector, #使用链接数据库的模块
maxusage = None, #一个链接最多被使用的次数,None表示无限制
setsession = [], #开始会话前执行的命令
ping = 0, #ping MySQL服务端,检查服务是否可用
closeable = False, #conn.close()实际上被忽略,供下次使用,直到线程关闭,自动关闭链接,而等于True时,conn.close()真的被关闭
threadlocal = None, # 本线程独享值的对象,用于保存链接对象
host = '127.0.0.1',
port = 3308,
user = 'root',
password = '',
database = 'test',
charset = 'utf8'
)
conns=[]
db=dbutil.MySQLUtil()
for item in range(10):
conn = pool.connection()
conns.append(conn)
print(item)
db.connection=conn
# 查询数据库连接的id
datas=db.queryone("SELECT CONNECTION_ID()")
print(datas)
time.sleep(50)
从打印结果可知,同一个连接,在反复使用