- A+
目录
一、介绍
DBUtils是一套Python数据库连接池包,并允许对非线程安全的数据库接口进行线程安全包装。
DBUtils是一套工具,提供到数据库的可靠、持久和池连接,可以在各种多线程环境中使用,如Python或其他web应用服务器的web ware。
DBUtils提供两种外部接口:
* PersistentDB :提供线程专用的数据库连接,并自动管理连接。
* PooledDB :提供线程间可共享的数据库连接,并自动管理连接。!!注意!!DBUtils不仅支持mysql数据库模块
1-1 安装
二、DBUtils简单使用 - 两种方式
2-1 方式一、PersistentDB - 每个线程创立一个连接(不推荐)
使用总结
- POOL = PersistentDB() - 实例化池对象,写入池的配置信息;为每个线程创立连接
- conn = POOL.connection() - 池连接
- conn.cursor().execute('select * from user') - 执行SQL语句
- conn.cursor().fetchall() - 获取执行SQL后的返回
- conn.close() - 未关闭连接,只是将连接放回池子,仅供自己的线程再次使用;当线程终止时,连接自动关闭;
from DBUtils.PersistentDB import PersistentDB
creator=pymysql, # 使用链接数据库的模块
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。
# ping MySQL服务端,检查是否服务可用。
# 如果为False时, conn.close() 实际上被忽略,供下次使用,再线程关闭时,才会自动关闭链接。如果为True时, conn.close()则关闭链接,那么再次调用pool.connection时就会报错,因为已经真的关闭了连接(pool.steady_connection()可以获取一个新的链接)
threadlocal=None, # 本线程独享值得对象,用于保存链接对象,如果链接对象被重置
conn = POOL.connection(shareable=False)
cursor = conn.cursor()
cursor.execute('select * from user')
result = cursor.fetchall()
if __name__ == '__main__':
2-2 方式二、PooledDB - 创建一批连接,供所有线程共享使用(推荐)
使用总结
- POOL = PooledDB() - 实例化池对象,写入池的配置信息;创建一批连接放入连接池,共享使用
- conn = POOL.connection() - 池连接
- conn.cursor().execute('select * from user') - 执行SQL语句
- conn.cursor().fetchall() - 获取执行SQL后的返回
- conn.close() - 未关闭连接,只是将连接放回池子,供所有线程共享使用;当线程终止时,连接自动关闭;
from DBUtils.PooledDB import PooledDB
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5, # 链接池中最多闲置的链接,0和None不限制
# 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。
# ping MySQL服务端,检查是否服务可用。
# 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常
# 否则 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
# 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
# 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
# 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
conn = POOL.connection()
# print(th, '链接被拿走了', conn1._con)
# print(th, '池子里目前有', pool._idle_cache, '\r\n')
cursor = conn.cursor()
cursor.execute('select * from user')
result = cursor.fetchall()
if __name__ == '__main__':
三、抽象处理
总结
- 将连接配置单独放置到settings.py文件中;不同的数据库模块使用不同的类实现配置
- 视图函数内封装对数据库开、关、查的操作;抽象为SQLHelper类
from datetime import timedelta
from DBUtils.PooledDB import PooledDB, SharedDBConnection
SECRET_KEY = "umsuldfsdflskjdf"
PERMANENT_SESSION_LIFETIME = timedelta(minutes=20)
SESSION_REFRESH_EACH_REQUEST= True
SESSION_TYPE = "redis"
PYMYSQL_POOL = PooledDB(
creator=pymysql, # 使用链接数据库的模块
maxconnections=6, # 连接池允许的最大连接数,0和None表示不限制连接数
mincached=2, # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
maxcached=5, # 链接池中最多闲置的链接,0和None不限制
# 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
blocking=True, # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
# 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
host='127.0.0.1',
password='123456',
database='s8day127db',
class ProductionConfig(Config):
SESSION_REDIS = Redis(host='192.168.0.94', port='6379')
class DevelopmentConfig(Config):
SESSION_REDIS = Redis(host='127.0.0.1', port='6379')
class TestingConfig(Config):
from settings import Config
POOL = Config.PYMYSQL_POOL
conn = POOL.connection()
cursor = conn.cursor(cursor=cursor)
return conn,cursor
def close(conn,cursor):
def fetch_one(cls,sql,args,cursor =pymysql.cursors.DictCursor):
conn,cursor = cls.open(cursor)
cursor.execute(sql, args)
obj = cursor.fetchone()
cls.close(conn,cursor)
def fetch_all(cls,sql, args,cursor =pymysql.cursors.DictCursor):
conn, cursor = cls.open(cursor)
cursor.execute(sql, args)
obj = cursor.fetchall()
cls.close(conn, cursor)
obj = SQLHelper.fetch_one("select id,name from users where name=%(user)s and pwd=%(pwd)s", form.data)
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫