Python实现Mysql数据库连接池实例详解


Posted in Python onApril 11, 2017

python连接Mysql数据库:

Python编程中可以使用MySQLdb进行数据库的连接及诸如查询/插入/更新等操作,但是每次连接MySQL数据库请求时,都是独立的去请求访问,相当浪费资源,而且访问数量达到一定数量时,对mysql的性能会产生较大的影响。因此,实际使用中,通常会使用数据库的连接池技术,来访问数据库达到资源复用的目的。
数据库连接池

Python实现Mysql数据库连接池实例详解

python的数据库连接池包 DBUtils:

DBUtils是一套Python数据库连接池包,并允许对非线程安全的数据库接口进行线程安全包装。DBUtils来自Webware for Python。

DBUtils提供两种外部接口:

* PersistentDB :提供线程专用的数据库连接,并自动管理连接。
* PooledDB :提供线程间可共享的数据库连接,并自动管理连接。

下载地址:DBUtils   下载解压后,使用python setup.py install 命令进行安装

下面利用MySQLdb和DBUtils建立自己的mysql数据库连接池工具包

在工程目录下新建package命名为:dbConnecttion,并新建module命名为MySqlConn,下面是MySqlConn.py,该模块创建Mysql的连接池对象,并创建了如查询/插入等通用的操作方法。该部分代码实现如下:

# -*- coding: UTF-8 -*- 
""" 
Created on 2016年5月7日 
 
@author: baocheng 
1、执行带参数的SQL时,请先用sql语句指定需要输入的条件列表,然后再用tuple/list进行条件批配 
2、在格式SQL中不需要使用引号指定数据类型,系统会根据输入参数自动识别 
3、在输入的值中不需要使用转意函数,系统会自动处理 
""" 
 
import MySQLdb 
from MySQLdb.cursors import DictCursor 
from DBUtils.PooledDB import PooledDB 
#from PooledDB import PooledDB 
import Config 
 
""" 
Config是一些数据库的配置文件 
""" 
 
class Mysql(object): 
 """ 
 MYSQL数据库对象,负责产生数据库连接 , 此类中的连接采用连接池实现获取连接对象:conn = Mysql.getConn() 
   释放连接对象;conn.close()或del conn 
 """ 
 #连接池对象 
 __pool = None 
 def __init__(self): 
  #数据库构造函数,从连接池中取出连接,并生成操作游标 
  self._conn = Mysql.__getConn() 
  self._cursor = self._conn.cursor() 
 
 @staticmethod 
 def __getConn(): 
  """ 
  @summary: 静态方法,从连接池中取出连接 
  @return MySQLdb.connection 
  """ 
  if Mysql.__pool is None: 
   __pool = PooledDB(creator=MySQLdb, mincached=1 , maxcached=20 , 
        host=Config.DBHOST , port=Config.DBPORT , user=Config.DBUSER , passwd=Config.DBPWD , 
        db=Config.DBNAME,use_unicode=False,charset=Config.DBCHAR,cursorclass=DictCursor) 
  return __pool.connection() 
 
 def getAll(self,sql,param=None): 
  """ 
  @summary: 执行查询,并取出所有结果集 
  @param sql:查询SQL,如果有查询条件,请只指定条件列表,并将条件值使用参数[param]传递进来 
  @param param: 可选参数,条件列表值(元组/列表) 
  @return: result list(字典对象)/boolean 查询到的结果集 
  """ 
  if param is None: 
   count = self._cursor.execute(sql) 
  else: 
   count = self._cursor.execute(sql,param) 
  if count>0: 
   result = self._cursor.fetchall() 
  else: 
   result = False 
  return result 
 
 def getOne(self,sql,param=None): 
  """ 
  @summary: 执行查询,并取出第一条 
  @param sql:查询SQL,如果有查询条件,请只指定条件列表,并将条件值使用参数[param]传递进来 
  @param param: 可选参数,条件列表值(元组/列表) 
  @return: result list/boolean 查询到的结果集 
  """ 
  if param is None: 
   count = self._cursor.execute(sql) 
  else: 
   count = self._cursor.execute(sql,param) 
  if count>0: 
   result = self._cursor.fetchone() 
  else: 
   result = False 
  return result 
 
 def getMany(self,sql,num,param=None): 
  """ 
  @summary: 执行查询,并取出num条结果 
  @param sql:查询SQL,如果有查询条件,请只指定条件列表,并将条件值使用参数[param]传递进来 
  @param num:取得的结果条数 
  @param param: 可选参数,条件列表值(元组/列表) 
  @return: result list/boolean 查询到的结果集 
  """ 
  if param is None: 
   count = self._cursor.execute(sql) 
  else: 
   count = self._cursor.execute(sql,param) 
  if count>0: 
   result = self._cursor.fetchmany(num) 
  else: 
   result = False 
  return result 
 
 def insertOne(self,sql,value): 
  """ 
  @summary: 向数据表插入一条记录 
  @param sql:要插入的SQL格式 
  @param value:要插入的记录数据tuple/list 
  @return: insertId 受影响的行数 
  """ 
  self._cursor.execute(sql,value) 
  return self.__getInsertId() 
 
 def insertMany(self,sql,values): 
  """ 
  @summary: 向数据表插入多条记录 
  @param sql:要插入的SQL格式 
  @param values:要插入的记录数据tuple(tuple)/list[list] 
  @return: count 受影响的行数 
  """ 
  count = self._cursor.executemany(sql,values) 
  return count 
 
 def __getInsertId(self): 
  """ 
  获取当前连接最后一次插入操作生成的id,如果没有则为0 
  """ 
  self._cursor.execute("SELECT @@IDENTITY AS id") 
  result = self._cursor.fetchall() 
  return result[0]['id'] 
 
 def __query(self,sql,param=None): 
  if param is None: 
   count = self._cursor.execute(sql) 
  else: 
   count = self._cursor.execute(sql,param) 
  return count 
 
 def update(self,sql,param=None): 
  """ 
  @summary: 更新数据表记录 
  @param sql: SQL格式及条件,使用(%s,%s) 
  @param param: 要更新的 值 tuple/list 
  @return: count 受影响的行数 
  """ 
  return self.__query(sql,param) 
 
 def delete(self,sql,param=None): 
  """ 
  @summary: 删除数据表记录 
  @param sql: SQL格式及条件,使用(%s,%s) 
  @param param: 要删除的条件 值 tuple/list 
  @return: count 受影响的行数 
  """ 
  return self.__query(sql,param) 
 
 def begin(self): 
  """ 
  @summary: 开启事务 
  """ 
  self._conn.autocommit(0) 
 
 def end(self,option='commit'): 
  """ 
  @summary: 结束事务 
  """ 
  if option=='commit': 
   self._conn.commit() 
  else: 
   self._conn.rollback() 
 
 def dispose(self,isEnd=1): 
  """ 
  @summary: 释放连接池资源 
  """ 
  if isEnd==1: 
   self.end('commit') 
  else: 
   self.end('rollback'); 
  self._cursor.close() 
  self._conn.close()

配置文件模块Cnofig,包括数据库的连接信息/用户名密码等:

#coding:utf-8 
''''' 
Created on 2016年5月7日 
 
@author: baocheng 
''' 
DBHOST = "localhost" 
DBPORT = 33606 
DBUSER = "zbc" 
DBPWD = "123456" 
DBNAME = "test" 
DBCHAR = "utf8"

创建test模块,测试一下使用连接池进行mysql访问:

#coding:utf-8 
''''' 
 
@author: baocheng 
''' 
from MySqlConn import Mysql 
from _sqlite3 import Row 
 
#申请资源 
mysql = Mysql() 
 
sqlAll = "SELECT tb.uid as uid, group_concat(tb.goodsname) as goodsname FROM ( SELECT goods.uid AS uid, IF ( ISNULL(goodsrelation.goodsname), goods.goodsID, goodsrelation.goodsname ) AS goodsname FROM goods LEFT JOIN goodsrelation ON goods.goodsID = goodsrelation.goodsId ) tb GROUP BY tb.uid" 
result = mysql.getAll(sqlAll) 
if result : 
 print "get all" 
 for row in result : 
  print "%s\t%s"%(row["uid"],row["goodsname"]) 
sqlAll = "SELECT tb.uid as uid, group_concat(tb.goodsname) as goodsname FROM ( SELECT goods.uid AS uid, IF ( ISNULL(goodsrelation.goodsname), goods.goodsID, goodsrelation.goodsname ) AS goodsname FROM goods LEFT JOIN goodsrelation ON goods.goodsID = goodsrelation.goodsId ) tb GROUP BY tb.uid" 
result = mysql.getMany(sqlAll,2) 
if result : 
 print "get many" 
 for row in result : 
  print "%s\t%s"%(row["uid"],row["goodsname"])   
   
   
result = mysql.getOne(sqlAll) 
print "get one" 
print "%s\t%s"%(result["uid"],result["goodsname"]) 
 
#释放资源 
mysql.dispose()

当然,还有很多其他参数可以配置:

  • dbapi :数据库接口
  • mincached :启动时开启的空连接数量
  • maxcached :连接池最大可用连接数量
  • maxshared :连接池最大可共享连接数量
  • maxconnections :最大允许连接数量
  • blocking :达到最大数量时是否阻塞
  • maxusage :单个连接最大复用次数

根据自己的需要合理配置上述的资源参数,以满足自己的实际需要。

至此,python中的mysql连接池实现完了,下次就直接拿来用就好了。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Python 相关文章推荐
跟老齐学Python之不要红头文件(2)
Sep 28 Python
python中执行shell的两种方法总结
Jan 10 Python
利用python写个下载teahour音频的小脚本
May 08 Python
Python实现上下班抢个顺风单脚本
Feb 07 Python
代码讲解Python对Windows服务进行监控
Feb 11 Python
详解Django中类视图使用装饰器的方式
Aug 12 Python
python爬虫之遍历单个域名
Nov 20 Python
python3使用Pillow、tesseract-ocr与pytesseract模块的图片识别的方法
Feb 26 Python
python GUI库图形界面开发之PyQt5窗口布局控件QStackedWidget详细使用方法
Feb 27 Python
使用tensorflow实现VGG网络,训练mnist数据集方式
May 26 Python
python不到50行代码完成了多张excel合并的实现示例
May 28 Python
numpy的Fancy Indexing和array比较详解
Jun 11 Python
详解Python中类的定义与使用
Apr 11 #Python
python获取指定时间差的时间实例详解
Apr 11 #Python
一个基于flask的web应用诞生 组织结构调整(7)
Apr 11 #Python
一个基于flask的web应用诞生 记录用户账户登录状态(6)
Apr 11 #Python
一个基于flask的web应用诞生 用户注册功能开发(5)
Apr 11 #Python
一个基于flask的web应用诞生 flask和mysql相连(4)
Apr 11 #Python
一个基于flask的web应用诞生 bootstrap框架美化(3)
Apr 11 #Python
You might like
CodeIgniter启用缓存和清除缓存的方法
2014/06/12 PHP
tp5 sum某个字段相加得到总数的例子
2019/10/18 PHP
TP5框架页面跳转样式操作示例
2020/04/05 PHP
javascript 动态添加表格行
2006/06/22 Javascript
Jquery的hover方法让鼠标经过li时背景变色
2013/09/06 Javascript
鼠标移到div,浮层显示明细,弹出层与div的上边距左边距重合(示例代码)
2013/12/14 Javascript
使用requestAnimationFrame实现js动画性能好
2015/08/06 Javascript
每天一篇javascript学习小结(基础知识)
2015/11/10 Javascript
常常会用到的截取字符串substr()、substring()、slice()方法详解
2015/12/16 Javascript
JavaScript中Form表单技术汇总(推荐)
2016/06/26 Javascript
全面了解JS中的匿名函数
2016/06/29 Javascript
JavaScript结合Bootstrap仿微信后台多图文界面管理
2016/07/22 Javascript
前端JS面试中常见的算法问题总结
2016/12/23 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
2017/07/21 Javascript
js微信应用场景之微信音乐相册案例分享
2017/08/11 Javascript
JS实现前端缓存的方法
2017/09/21 Javascript
JavaScript实现二叉树的先序、中序及后序遍历方法详解
2017/10/26 Javascript
JS中精巧的自动柯里化实现方法
2017/12/12 Javascript
Vuex 单状态库与多模块状态库详解
2018/12/11 Javascript
Vue中axios拦截器如何单独配置token
2019/12/27 Javascript
微信小程序scroll-view点击项自动居中效果的实现
2020/03/25 Javascript
python网络编程学习笔记(九):数据库客户端 DB-API
2014/06/09 Python
python获取程序执行文件路径的方法(推荐)
2018/04/26 Python
python爬虫的数据库连接问题【推荐】
2018/06/25 Python
实例详解Matlab 与 Python 的区别
2019/04/26 Python
PyCharm 创建指定版本的 Django(超详图解教程)
2019/06/18 Python
Python对wav文件的重采样实例
2020/02/25 Python
python爬虫使用requests发送post请求示例详解
2020/08/05 Python
俄罗斯Sportmarket体育在线商店:用于旅游和户外活动
2019/11/12 全球购物
工地资料员岗位职责
2013/12/31 职场文书
11.9消防日宣传标语
2014/10/08 职场文书
财务稽核岗位职责
2015/04/13 职场文书
画展观后感
2015/06/17 职场文书
python源码剖析之PyObject详解
2021/05/18 Python
FP-growth算法发现频繁项集——构建FP树
2021/06/24 Python
Redis批量生成数据的实现
2022/06/05 Redis