python数据库连接池DBUtils

内容:

1.DBUtils介绍

2.DBUtils两种连接模式

3.DBUtils实际使用

 

参考:http://www.cnblogs.com/wupeiqi/articles/8184686.html

 

 

1.DBUtils介绍

DBUtils是Python的一个用于实现数据库连接池的模块,我们可以使用DBUtils分别的创建数据库连接池

安装:pip install DBUtils

为什么要使用数据库连接池:如果没有连接池,使用pymysql来连接数据库时,单线程应用完全没有问题,但如果涉及到多线程应用那么就需要加锁,一旦加锁那么连接势必就会排队等待,当请求比较多时,性能就会降低了

 

 

2.DBUtils两种连接模式

两种连接模式:

  • 模式一:为每个线程创建一个连接,线程即使调用了close方法,也不会关闭,只是把连接重新放到连接池,供自己线程再次使用。当线程终止时,连接自动关闭。  --> 一般不用这种模式
  • 模式二:创建一批连接到连接池,供所有线程共享使用。PS:由于pymysql、MySQLdb等threadsafety值为1,所以该模式连接池中的线程会被所有线程共享

模式一实例:

 1 POOL = PersistentDB(
 2     creator=pymysql,  # 使用链接数据库的模块
 3     maxusage=None,    # 一个链接最多被重复使用的次数,None表示无限制
 4     setsession=[],    # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
 5     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
 6     closeable=False,  # 如果为False时, conn.close() 实际上被忽略,conn继续供下次使用,只有在线程关闭时才会自动关闭连接。如果为True时, conn.close()则关闭链接,那么再次调用pool.connection时就会报错,因为已经真的关闭了连接(pool.steady_connection()可以获取一个新的链接)
 7     threadlocal=None, # 本线程独享值得对象,用于保存链接对象,如果链接对象被重置
 8     host='127.0.0.1',
 9     port=3306,
10     user='root',
11     password='root',
12     database='test',
13     charset='utf8'
14 )
15 
16 def func():
17     conn = POOL.connection(shareable=False)
18     cursor = conn.cursor()
19     cursor.execute('select * from users')
20     result = cursor.fetchall()
21     cursor.close()
22     conn.close()
23 
24 func()

 

模式二实例:

 1 import time
 2 import pymysql
 3 import threading
 4 from DBUtils.PooledDB import PooledDB, SharedDBConnection
 5 POOL = PooledDB(
 6     creator=pymysql,  # 使用链接数据库的模块
 7     maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
 8     mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
 9     maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
10     maxshared=3,  # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
11     blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
12     maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
13     setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
14     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
15     host='127.0.0.1',
16     port=3306,
17     user='root',
18     password='root',
19     database='test',
20     charset='utf8'
21 )
22 
23 
24 def func():
25     # 检测当前正在运行连接数的是否小于最大链接数,如果不小于则等待或报raise TooManyConnections异常
26     # 否则
27     # 则优先去初始化时创建的链接中获取链接 SteadyDBConnection。
28     # 然后将SteadyDBConnection对象封装到PooledDedicatedDBConnection中并返回。
29     # 如果最开始创建的链接没有链接,则去创建一个SteadyDBConnection对象,再封装到PooledDedicatedDBConnection中并返回。
30     # 一旦关闭链接后,连接就返回到连接池让后续线程继续使用。
31     conn = POOL.connection()
32 
33     # print(th, '链接被拿走了', conn1._con)
34     # print(th, '池子里目前有', pool._idle_cache, '\r\n')
35 
36     cursor = conn.cursor()
37     cursor.execute('select * from tb1')
38     result = cursor.fetchall()
39     conn.close()
40 
41 
42 func()

 

 

3.DBUtils实际使用

下面是DBUtils在flask中的实际使用:

 1 # encoding: utf-8
 2 # __author__ = "wyb"
 3 # date: 2018/11/7
 4 import pymysql
 5 from DBUtils.PooledDB import PooledDB
 6 from flask import Flask
 7 
 8 POOL = PooledDB(
 9     creator=pymysql,    # 使用链接数据库的模块
10     maxconnections=6,   # 连接池允许的最大连接数,0和None表示不限制连接数
11     mincached=2,        # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
12     maxcached=5,        # 链接池中最多闲置的链接,0和None不限制
13     maxshared=3,        # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
14     blocking=True,      # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
15     maxusage=None,      # 一个链接最多被重复使用的次数,None表示无限制
16     setsession=[],      # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
17     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
18     host='127.0.0.1',
19     port=3306,
20     user='root',
21     password='root',
22     database='test',
23     charset='utf8'
24 )
25 
26 
27 # SQL相关操作写这里面 -> 增删改查
28 class SQLHelper(object):
29     def __init__(self):
30         self.conn = POOL.connection()
31         self.cursor = self.conn.cursor()
32 
33     def close(self):
34         self.cursor.close()
35         self.conn.close()
36 
37     def fetch_one(self, sql, args):
38         self.cursor.execute(sql, args)
39         result = self.cursor.fetchone()
40         self.close()
41 
42         return result
43 
44     def fetch_all(self, sql, args):
45         self.cursor.execute(sql, args)
46         result = self.cursor.fetchall()
47         self.close()
48 
49         return result
50 
51 
52 app = Flask(__name__)
53 
54 
55 @app.route("/")
56 def hello():
57     obj = SQLHelper()
58     result = obj.fetch_all('select * from users', [])
59     print(result)
60     return 'hello world'
61 
62 
63 if __name__ == '__main__':
64     app.run(debug=True, host='0.0.0.0', port=8888)

 

posted @ 2018-11-07 18:07  woz333333  阅读(220)  评论(0编辑  收藏  举报