内容简介:Python-flask中数据库连接池DBUtils
一、DBUtils
DBUtils是 Python 的一个用于实现数据库连接池的模块。
连接池的三种模式:
第一种模式:
它的缺点:每一次请求反复创建数据库的链接,链接的次数太多
from flask import Flask
from db import POOL
import pymysql
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'
@app.route('/index')
def index():
# 第一步:缺点:每次请求反复创建数据库连接,连接数太多
# conn = pymysql.connect()
# cursor = conn.cursor()
# cursor.execute('select * from tb where id > %s',[5,])
# result = cursor.fetchall()
# cursor.close()
# conn.close()
# print(result)
return '执行成功'
if __name__ == '__main__':
# app.__call__
app.run()
模式一
第二种模式:
它的缺点:不能支持并发
from flask import Flask
from db import POOL
import pymysql
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'
@app.route('/index')
def index():
# 第二步:缺点,不能支持并发
# pymysql.threadsafety
# with LOCK:
# cursor = CONN.cursor()
# cursor.execute('select * from tb where id > %s', [5, ])
# result = cursor.fetchall()
# cursor.close()
return '执行成功'
if __name__ == '__main__':
# app.__call__
app.run()
模式二
第三种模式:
它是基于DBUtils实现数据库连接池
-为每个线程创建一个链接,该线程关闭时,不是真正的关闭,本线程再次调用时,还是使用的最开始的创建的链接,知道线程终止,数据库链接才关闭
-创建一个连接池(10个链接),为所有线程提供链接,使用时来进行获取,使用完毕时,再次放回到连接池。
from flask import Flask
from db import POOL
import pymysql
app = Flask(__name__)
app.secret_key ='sdfsdfsdf'
@app.route('/index')
def index():
# 第三步:基于DBUtils实现数据连接池
# - 为没个线程创建一个连接,该线程关闭时,不是真正关闭;本线程再次调用时,还是使用的最开始创建的连接。直到线程终止,数据库连接才关闭。
# - 创建一个连接池(10个连接),为所有线程提供连接,使用时来进行获取,使用完毕后,再次放回到连接池。
# PS:
conn = POOL.connection()
cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
conn.close()
return '执行成功'
if __name__ == '__main__':
# app.__call__
app.run()
模式三
DBUtils的应用:
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
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=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# 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',
port=3306,
user='root',
password='123',
database='pooldb',
charset='utf8'
)
本地线程:
import threading
import time
# 本地线程对象
local_values = threading.local()
def func(num):
"""
# 第一个线程进来,本地线程对象会为他创建一个
# 第二个线程进来,本地线程对象会为他创建一个
{
线程1的唯一标识:{name:1},
线程2的唯一标识:{name:2},
}
:param num:
:return:
"""
local_values.name = num # 4
# 线程停下来了
time.sleep(2)
# 第二个线程: local_values.name,去local_values中根据自己的唯一标识作为key,获取value中name对应的值
print(local_values.name, threading.current_thread().name)
for i in range(5):
th = threading.Thread(target=func, args=(i,), name='线程%s' % i)
th.start()
本地线程
模式一:
"""
为每个线程创建一个连接,thread.local实现。
"""
from DBUtils.PersistentDB import PersistentDB
import pymysql
POOL = PersistentDB(
creator=pymysql, # 使用链接数据库的模块
maxusage=None, # 一个链接最多被重复使用的次数,None表示无限制
setsession=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# 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
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='123',
database='pooldb',
charset='utf8'
)
def func():
# conn = SteadyDBConnection()
conn = POOL.connection()
cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
cursor.close()
conn.close() # 不是真的关闭,而是假的关闭。 conn = pymysql.connect() conn.close()
conn = POOL.connection()
cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
cursor.close()
conn.close()
import threading
for i in range(10):
t = threading.Thread(target=func)
t.start()
模式一
模式二:
import time
import pymysql
import threading
from DBUtils.PooledDB import PooledDB, SharedDBConnection
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=[], # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
ping=0,
# 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',
port=3306,
user='root',
password='123',
database='pooldb',
charset='utf8'
)
def func():
# 检测当前正在运行连接数的是否小于最大链接数,如果不小于则:等待或报raise TooManyConnections异常
# 否则
# 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
# 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
# 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
# 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
# PooledDedicatedDBConnection
conn = POOL.connection()
# print(th, '链接被拿走了', conn1._con)
# print(th, '池子里目前有', pool._idle_cache, '\r\n')
cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
conn.close()
conn = POOL.connection()
# print(th, '链接被拿走了', conn1._con)
# print(th, '池子里目前有', pool._idle_cache, '\r\n')
cursor = conn.cursor()
cursor.execute('select * from tb1')
result = cursor.fetchall()
conn.close()
func()
模式二
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- EF Core 小坑:DbContextPool 会引起数据库连接池连接耗尽
- 数据库连接池
- 数据库连接池设置
- 怎样获知数据库的连接属性?
- 怎样获知数据库的连接属性?
- Laravel 使用多个数据库连接
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Data Structures and Algorithm Analysis in Java
Mark A. Weiss / Pearson / 2011-11-18 / GBP 129.99
Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course wa......一起来看看 《Data Structures and Algorithm Analysis in Java》 这本书的介绍吧!