数据库连接池,主要用于多线程,为了防止多线程同时对数据库进行操作出现混乱。创建数据库线程池,维护n个数据库连接供程序使用
import threadingimport pymysqlfrom DBUtils.PooledDB import PooledDBclass SqlHelper(object):def __init__(self):self.pool = PooledDB(# 数据库驱动模块creator=pymysql,# 线程池最大连接数maxconnections=6,# 初始化连接池时创建的连接数mincached=2,# 池中空闲连接的最大数量maxcached=5,# 池中共享连接的最大数量maxshared=3,#默认False,即达到最大连接数时,再取新连接将会报错,True,达到最大连接数时,新连接阻塞,等待连接数减少再连接blocking=True,# 连接的最大使用次数maxusage=None,# 确定何时使用ping()检查连接。默认1,即当连接被取走,做一次ping操作。0是从不ping,1是默认,2是当该连接创建游标时ping,4是执行sql语句时ping,7是总是pingping=0,host='127.0.0.1',port=3306,user='blogadmin',password='blogpwd',database='flask_blog',charset='utf8',)self.local = threading.local()# 打开连接def open(self):conn = self.pool.connection()cursor = conn.cursor()return conn, cursor# 关闭连接def close(self, cursor, conn):cursor.close()conn.close()# 查询全部def fetchall(self, sql, *args):conn, cursor = self.open()cursor.execute(sql, *args)result = cursor.fetchall()self.close(cursor, conn)return result# 查询一条def fetchone(self, sql, *args):conn, cursor = self.open()cursor.execute(sql, *args)result = cursor.fetchone()self.close(cursor, conn)return result# 插入一条def insert(self, sql, *args):conn, cursor = self.open()try:cursor.execute(sql, *args)# 食物提交conn.commit()self.close(cursor, conn)return Trueexcept:# 事务回滚conn.rollback()return Falsedef __enter__(self):conn, cursor = self.open()rv = getattr(self.local,'stack',None)if not rv:self.local.stack = [(conn, cursor)]else:rv.append((conn, cursor))self.local.stack = rvreturn cursordef __exit__(self):rv = getattr(self.local,'stack',None)if not rv:del self.local.stackreturnelse:conn, cursor = self.local.stack.pop()self.close(conn, cursor)def __new__(cls, *args, **kwargs):if not hasattr(SqlHelper, '_instance'):SqlHelper._instance = super().__new__(cls)return SqlHelper._instancedb = SqlHelper()# with db as c1:# c1.execute('select sleep(1)')
