转:https://blog.youkuaiyun.com/qq_29113041/article/details/99690070
为什么要用数据库连接池
平常可能习惯使用pymysql或者一些数据库连接包去跟数据库交互,代码可能是这样的:
import pymysql
config = {
'host': config_template['MYSQL']['HOST'],
'port': config_template['MYSQL']['PORT'],
'user': config_template['MYSQL']['USER'],
'password': config_template['MYSQL']['PASSWD'],
'db': config_template['MYSQL']['DB'],
'charset': config_template['MYSQL']['CHARSET'],
'cursorclass': pymysql.cursors.DictCursor
}
def db_conn():
conn = pymysql.connect(**config)
cursor = conn.cursor()
return conn,cursor
大概就是这么个意思,将连接数据库封装为一个方法,每次需要连接的时候调用该方法获取conn和cursor对象,但是这样会有损耗,因为每次都需要 建立连接->执行数据库操作->释放连接。而数据库连接池为维护一个保存有多个数据库连接的池子,每次需要连接数据库时,从连接池中取出一个连接进行使用即可,使用完毕后连接不会释放,而是归还给连接池进行管理,节省了不断建立连接和释放连接的过程。
使用DBUtils建立数据库连接池
import pymysql
from g_conf.config import config_template
from DBUtils.PooledDB import PooledDB
class MysqlPool:
config = {
'creator': pymysql,
'host': config_template['MYSQL']['HOST'],
'port': config_template['MYSQL']['PORT'],
'user': config_template['MYSQL']['USER'],
'password': config_template['MYSQL']['PASSWD'],
'db': config_template['MYSQL']['DB'],
'charset': config_template['MYSQL']['CHARSET'],
'maxconnections': 70, # 连接池最大连接数量
'cursorclass': pymysql.cursors.DictCursor
}
pool = PooledDB(**config)
def __enter__(self):
self.conn = MysqlPool.pool.connection()
self.cursor = self.conn.cursor()
return self
def __exit__(self, type, value, trace):
self.cursor.close()
self.conn.close()
可以看到,通过DBUtils,实例化一个PooledDB对象作为MysqlPool类的类属性,通过重写__enter__和__exit__方法让我们在进入with语句时从连接池中获取到数据库连接,在with语句结束后,自动释放连接池,归还给连接池。
使用方式与普通连接mysql并无区别,使用with语句调用即可:
def func(tar_id):
with MysqlPool() as db:
db.cursor.execute('YOUR_SQL')
db.conn.commit()
装饰器用法:
def db_conn(func):
def wrapper(*args, **kw):
with MysqlPool() as db:
result = func(db, *args, **kw)
return result
return wrapper
@db_conn
def update_info(db, *args, **kw):
try:
db.cursor.execute("YOUR_SQL")
db.conn.commit()
return 0
except Exception as e:
db.conn.rollback()
return 1
DBUtils还有很多强大的功能,如果有更多的需求可以自行查阅相关文档,本文仅仅是抛砖引玉,提供一种数据库连接池的使用方法。