DBUtils 是Python 的一个用于实现数据库连接池的模块。

此连接池有两种连接模式:

DBUtils :提供两种外部接口:

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

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

介绍

PersistentDB模式

为每个线程创建一个连接,线程即使调用了 close 方法,也不会关闭,只是把链接重新放到链接池,供自己线程再次使用,当线程终止时,链接自动关闭。

from DBUtils.PersistentDB import PersistentDB
import pymysql
POOL = PersistentDB(
creator=pymysql, # 使用链接数据库的模块
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。
ping=0, # ping MySQL服务端,检查是否服务可用。
closeable=False, # 如果为False时, conn.close() 实际上被忽略,供下次使用,再线程关闭时,才会自动关闭链接。如果为True时, conn.close()则关闭链接,那么再次调用pool.connection时就会报错,因为已经真的关闭了连接(pool.steady_connection()可以获取一个新的链接)
threadlocal=None, # 本线程独享值得对象,用于保存链接对象,如果链接对象被重置
host='127.0.0.1',
port=3306,
user='root',
password='',
database='test',
charset='utf8'
) def func():
conn = POOL.connection(shareable=False)
cursor = conn.cursor()
cursor.execute('select * from user')
result = cursor.fetchall()
print(result)
cursor.close()
conn.close()
if __name__ == '__main__': func()

PooledDB模式

创建一批连接到连接池,供所有线程共享使用。

import pymysql

from DBUtils.PooledDB import PooledDB
POOL = PooledDB(
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=[], # 开始会话前执行的命令列表。
ping=0, # ping MySQL服务端,检查是否服务可用。
host='127.0.0.1',
port=3306,
user='root',
password='',
database='test',
charset='utf8'
) def func():
# 检测当前正在运行连接数的是否小于最大链接数,如果不小于则等待或报raise TooManyConnections异常
# 否则则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
# 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
# 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
# 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
conn = POOL.connection()
cursor = conn.cursor(pymysql.cursors.DictCursor)
cursor.execute('select * from user')
result = cursor.fetchall()
print(result)
conn.close() if __name__ == '__main__': func()

工具类

# TEST数据库信息
DB_TEST_HOST = "127.0.0.1"
DB_TEST_PORT = 3306
DB_TEST_DBNAME = ""
DB_TEST_USER = "root"
DB_TEST_PASSWORD = "root" # 数据库连接编码
DB_CHARSET = "utf8" # mincached : 启动时开启的闲置连接数量(缺省值 0 开始时不创建连接)
DB_MIN_CACHED = 10 # maxcached : 连接池中允许的闲置的最多连接数量(缺省值 0 代表不闲置连接池大小)
DB_MAX_CACHED = 10 # maxshared : 共享连接数允许的最大数量(缺省值 0 代表所有连接都是专用的)如果达到了最大数量,被请求为共享的连接将会被共享使用
DB_MAX_SHARED = 20 # maxconnecyions : 创建连接池的最大数量(缺省值 0 代表不限制)
DB_MAX_CONNECYIONS = 100 # blocking : 设置在连接池达到最大数量时的行为(缺省值 0 或 False 代表返回一个错误<toMany......>; 其他代表阻塞直到连接数减少,连接被分配)
DB_BLOCKING = True # maxusage : 单个连接的最大允许复用次数(缺省值 0 或 False 代表不限制的复用).当达到最大数时,连接会自动重新连接(关闭和重新打开)
DB_MAX_USAGE = 0 # setsession : 一个可选的SQL命令列表用于准备每个会话,如["set datestyle to german", ...]
DB_SET_SESSION = None

db_config.py

import pymysql
from DBUtils.PooledDB import PooledDB
import db_config as Config class ConnectionPool(object):
__pool = None def __enter__(self):
self.conn = self.__getConn()
self.cursor = self.conn.cursor()
print("数据库创建conn和cursor")
return self def __getConn(self):
if self.__pool is None:
self.__pool = PooledDB(creator=pymysql, mincached=Config.DB_MIN_CACHED, maxcached=Config.DB_MAX_CACHED,
maxshared=Config.DB_MAX_SHARED, maxconnections=Config.DB_MAX_CONNECYIONS,
blocking=Config.DB_BLOCKING, maxusage=Config.DB_MAX_USAGE,
setsession=Config.DB_SET_SESSION,
host=Config.DB_TEST_HOST, port=Config.DB_TEST_PORT,
user=Config.DB_TEST_USER, passwd=Config.DB_TEST_PASSWORD,
db=Config.DB_TEST_DBNAME, use_unicode=False, charset=Config.DB_CHARSET)
return self.__pool.connection() def __exit__(self, type, value, trace):
"""
@summary: 释放连接池资源
"""
self.cursor.close()
self.conn.close()
print("连接池释放conn和cursor") def getconn(self):
'''
从连接池中取出一个连接
'''
conn = self.__getConn()
cursor = conn.cursor(pymysql.cursors.DictCursor)
return cursor, conn def close(self):
'''
关闭连接归还给连接池
'''
self.cursor.close()
self.conn.close()
print("连接池释放conn和cursor") POOL = ConnectionPool() class MysqlHelper(object):
mysql = None def __init__(self):
self.db = POOL def __new__(cls, *args, **kwargs):
if not hasattr(cls, 'inst'):
cls.inst = super(MysqlHelper, cls).__new__(cls, *args, **kwargs)
return cls.inst def selectall(self, sql='', param=()):
'''
查询所有
''' try:
cursor, conn = self.execute(sql, param)
res = cursor.fetchall()
self.close(cursor, conn)
return res
except Exception as e:
print('selectall except ', e.args)
self.close(cursor, conn)
return None def selectone(self, sql='', param=()):
'''
查询一条
'''
try:
cursor, conn = self.execute(sql, param)
res = cursor.fetchone()
self.close(cursor, conn)
return res
except Exception as e:
print('selectone except ', e.args)
self.close(cursor, conn)
return None def insert(self, sql='', param=()):
'''
增加
'''
try:
cursor, conn = self.execute(sql, param)
print('============')
_id = cursor.lastrowid
print('_id ', _id)
conn.commit()
self.close(cursor, conn)
# 防止表中没有id返回0
if _id == 0:
return True
return _id
except Exception as e:
print('insert except ', e.args)
conn.rollback()
self.close(cursor, conn)
# self.conn.rollback()
return 0 def insertmany(self, sql='', param=()):
'''
增加多行
'''
cursor, conn = self.db.getconn()
try:
cursor.executemany(sql, param)
conn.commit()
self.close(cursor, conn)
return True
except Exception as e:
print('insert many except ', e.args)
conn.rollback()
self.close(cursor, conn)
return False def delete(self, sql='', param=()):
'''
删除
'''
try:
cursor, conn = self.execute(sql, param)
self.close(cursor, conn)
return True
except Exception as e:
print('delete except ', e.args)
conn.rollback()
self.close(cursor, conn)
return False def update(self, sql='', param=()):
'''
更新
'''
try:
cursor, conn = self.execute(sql, param)
self.close(cursor, conn)
return True
except Exception as e:
print('update except ', e.args)
conn.rollback()
self.close(cursor, conn)
return False @classmethod
def getInstance(self):
if MysqlHelper.mysql == None:
MysqlHelper.mysql = MysqlHelper()
return MysqlHelper.mysql # 执行命令
def execute(self, sql='', param=(), autoclose=False):
cursor, conn = self.db.getconn()
try:
if param:
cursor.execute(sql, param)
else:
cursor.execute(sql)
conn.commit()
if autoclose:
self.close(cursor, conn)
except Exception as e:
pass
return cursor, conn def executemany(self, list=[]):
'''
# 执行多条命令
'[{"sql":"xxx","param":"xx"}....]'
'''
cursor, conn = self.db.getconn()
try:
for order in list:
sql = order['sql']
param = order['param']
if param:
cursor.execute(sql, param)
else:
cursor.execute(sql)
conn.commit()
self.close(cursor, conn)
return True
except Exception as e:
print('execute failed========', e.args)
conn.rollback()
self.close(cursor, conn)
return False def close(self, cursor, conn):
cursor.close()
conn.close()
print("PT连接池释放con和cursor")

mysqlhelper

python之数据库连接池DBUtils的更多相关文章

  1. Python的数据库连接池DBUtils

    DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...

  2. Python数据库连接池---DBUtils

    Python数据库连接池DBUtils   DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...

  3. Python数据库连接池DBUtils

    Python数据库连接池DBUtils   DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不 ...

  4. Python数据库连接池DBUtils.PooledDB

    DBUtils 是一套用于管理数据库连接池的包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.最常用的两个外部接口是 PersistentDB 和 PooledDB,前者 ...

  5. Python 数据库连接池DButils

    常规的数据库链接存在的问题: 场景一: 缺点:每次请求反复创建数据库连接,连接数太多 import pymysql def index(): conn = pymysql.connect() curs ...

  6. Python数据库连接池DBUtils(基于pymysql模块连接数据库)

    安装 pip3 install DBUtils DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: # BDUtils数据库链接池: 模式一:基于threaing ...

  7. Python数据库连接池DBUtils详解

    what's the DBUtils DBUtils 是一套用于管理数据库连接池的Python包,为高频度高并发的数据库访问提供更好的性能,可以自动管理连接对象的创建和释放.并允许对非线程安全的数据库 ...

  8. Flask中使用数据库连接池 DBUtils ——(4)

    DBUtils是Python的一个用于实现数据库连接池的模块. 此连接池有两种连接模式: 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程 ...

  9. Flask的数据库连接池 DBUtils

    Flask是没有ORM的操作的,如果在flask中连接数据库有两种方式 一.pymysql 二.SQLAlchemy 是python操作数据库的以一个库,能够进行orm映射官网文档 sqlchemy ...

随机推荐

  1. vue-router的router.go(n)问题?

    <template> <div> <mt-navbar v-model="selected" class="container" ...

  2. MyBatis ResultMap Assocation 返回属性为null的问题

    Model: public class Employee { private Integer id; private String lastName; private String email; pr ...

  3. [转]SpringMVC+ Mybatis 配置多数据源 + 手动切换数据源

    正确可行的解决方法:使用Spring提供的AbstractRoutingDataSource类来根据请求路由到不同的数据源.具体做法是先设置两个不同的dataSource代表不同的数据源,再建一个总的 ...

  4. C# 在while循环中new的对象

    一: 问:那每次循环都会new一个A?那内存不是会满吗?还是说要把这个初始化对象的动作放到循环外面的写法会比较好? while(true) { A a = new A(); ... sleep(100 ...

  5. spring-boot子模块打包去掉BOOT-INF文件夹

    1.spring-boot maven打包,一般pom.xml文件里会加 <plugin> <groupId>org.springframework.boot</grou ...

  6. Ubuntu下Ansible安装和使用

    Ansible是一个批量部署的工具 参考:Ansible中文权威指南 1.安装 sudo apt-get install software-properties-common sudo apt-add ...

  7. .net framework 项目 build 出现 未能加载文件或程序集“netfx.force.conflicts”或它的某一个依赖项

    问题描述 Severity Code Description Project File Line Suppression State Error 未能加载文件或程序集"netfx.force ...

  8. centos7 nginx Failed to read PID from file /run/nginx.pid: Invalid argument 解决方法

    笔者在centos7上,配置nginx代理服务后, systemctl status nginx.service 提示错误 Failed to read PID from file /run/ngin ...

  9. Qt编写自定义控件2-进度条标尺

    前言 进度条标尺控件的应用场景一般是需要手动拉动进度,上面有标尺可以看到当前进度,类似于qslider控件,其实就是qslider+qprogressbar的杂交版本,不过我才用的是纯qpainter ...

  10. 茶馆小人书 (AFO)

    茶馆小人书 ——AFO ​ 乌云重重地压住了整个天际,阴风凛冽袭人,随着远方穹顶上的几声闷响,豆大的雨点便开始清洗这座城市.北方的雨,就是这么突然.任性,恰似北方人的性情,豪放不羁,一旦开始便不可收拾 ...