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. 【转载】systemctl命令完全指南

    Systemctl是一个systemd工具,主要负责控制systemd系统和服务管理器. Systemd是一个系统管理守护进程.工具和库的集合,用于取代System V初始进程.Systemd的功能是 ...

  2. Roslyn如何实现简单的代码提示

    假如需要实现一个代码编辑器,其中一个很重要的功能是实现代码提示,类似VS的代码智能提示.下面用Roslyn编译器来实现一个简单的代码提示功能. 代码提示,首先必须需要知道对象的类型信息,然后通过迭代获 ...

  3. Oracle 11gR2 RAC DBCA无法识别ASM磁盘组(ORA-19504,ORA-15045,ORA-17502,ORA-15081)

    ORA-19504: failed to create file "+DATA" ORA-15045: ASM file name '+DATA' is not in refere ...

  4. TensorFlow 图片resize方法

    参见这篇博客 tensorflow里面用于改变图像大小的函数是tf.image.resize_images(image, (w, h), method):image表示需要改变此存的图像,第二个参数改 ...

  5. MongoDB增删改查实例

    MongoDB之Java测试代码(DAO层),mongodbdao MongoInit.java是数据库初始化及连接类 MongoUtils.java是对mongodb的各种操作方法 MongoIni ...

  6. 开始学习Functional Programming

    打算先学F#, 再学Scala. 第一个F#程序 open System [<EntryPoint>] let main argv = let a = "Hello, World ...

  7. Kafka Eagle Consumers不显示

    原因: kafka.eagle.offset.storage配置有误 该配置的作用:# kafka offset storage -- Offset stored in a Kafka cluster ...

  8. saltstack通过jinja模板,将变量值增加到配置文件中?通过引用变量值修改配置文件?

    需求描述: 在使用saltstack的时候,有的时候,需要根据不同的变量来增加配置,比如,bind,监听端口,这些都可以通过变量写入,并且在配置的时候引用,下面是一个例子,用来演示,如何使用jinja ...

  9. [pig] pig 基础使用

    1.pig运行模式 本地模式: pig -x local 直接访问本地磁盘 集群模式: pig  或者 pig -x mapreduce 2.pig latin 交互 帮助信息 help 上传本地文件 ...

  10. J.U.C