Python实现Mysql数据库连接池

时间:2022-09-19 23:35:36

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的连接池对象,并创建了如查询/插入等通用的操作方法。该部分代码实现如下:

[python] view plain copy print?
  1. # -*- coding: UTF-8 -*-  
  2. """ 
  3. Created on 2016年5月7日 
  4.  
  5. @author: baocheng 
  6. 1、执行带参数的SQL时,请先用sql语句指定需要输入的条件列表,然后再用tuple/list进行条件批配 
  7. 2、在格式SQL中不需要使用引号指定数据类型,系统会根据输入参数自动识别 
  8. 3、在输入的值中不需要使用转意函数,系统会自动处理 
  9. """  
  10.    
  11. import MySQLdb  
  12. from MySQLdb.cursors import DictCursor  
  13. from DBUtils.PooledDB import PooledDB  
  14. #from PooledDB import PooledDB  
  15. import Config  
  16.   
  17. """ 
  18. Config是一些数据库的配置文件 
  19. """  
  20.    
  21. class Mysql(object):  
  22.     """ 
  23.     MYSQL数据库对象,负责产生数据库连接 , 此类中的连接采用连接池实现获取连接对象:conn = Mysql.getConn() 
  24.             释放连接对象;conn.close()或del conn 
  25.     """  
  26.     #连接池对象  
  27.     __pool = None  
  28.     def __init__(self):  
  29.         #数据库构造函数,从连接池中取出连接,并生成操作游标  
  30.         self._conn = Mysql.__getConn()  
  31.         self._cursor = self._conn.cursor()  
  32.   
  33.     @staticmethod  
  34.     def __getConn():  
  35.         """ 
  36.         @summary: 静态方法,从连接池中取出连接 
  37.         @return MySQLdb.connection 
  38.         """  
  39.         if Mysql.__pool is None:  
  40.             __pool = PooledDB(creator=MySQLdb, mincached=1 , maxcached=20 ,  
  41.                               host=Config.DBHOST , port=Config.DBPORT , user=Config.DBUSER , passwd=Config.DBPWD ,  
  42.                               db=Config.DBNAME,use_unicode=False,charset=Config.DBCHAR,cursorclass=DictCursor)  
  43.         return __pool.connection()  
  44.    
  45.     def getAll(self,sql,param=None):  
  46.         """ 
  47.         @summary: 执行查询,并取出所有结果集 
  48.         @param sql:查询SQL,如果有查询条件,请只指定条件列表,并将条件值使用参数[param]传递进来 
  49.         @param param: 可选参数,条件列表值(元组/列表) 
  50.         @return: result list(字典对象)/boolean 查询到的结果集 
  51.         """  
  52.         if param is None:  
  53.             count = self._cursor.execute(sql)  
  54.         else:  
  55.             count = self._cursor.execute(sql,param)  
  56.         if count>0:  
  57.             result = self._cursor.fetchall()  
  58.         else:  
  59.             result = False  
  60.         return result  
  61.    
  62.     def getOne(self,sql,param=None):  
  63.         """ 
  64.         @summary: 执行查询,并取出第一条 
  65.         @param sql:查询SQL,如果有查询条件,请只指定条件列表,并将条件值使用参数[param]传递进来 
  66.         @param param: 可选参数,条件列表值(元组/列表) 
  67.         @return: result list/boolean 查询到的结果集 
  68.         """  
  69.         if param is None:  
  70.             count = self._cursor.execute(sql)  
  71.         else:  
  72.             count = self._cursor.execute(sql,param)  
  73.         if count>0:  
  74.             result = self._cursor.fetchone()  
  75.         else:  
  76.             result = False  
  77.         return result  
  78.    
  79.     def getMany(self,sql,num,param=None):  
  80.         """ 
  81.         @summary: 执行查询,并取出num条结果 
  82.         @param sql:查询SQL,如果有查询条件,请只指定条件列表,并将条件值使用参数[param]传递进来 
  83.         @param num:取得的结果条数 
  84.         @param param: 可选参数,条件列表值(元组/列表) 
  85.         @return: result list/boolean 查询到的结果集 
  86.         """  
  87.         if param is None:  
  88.             count = self._cursor.execute(sql)  
  89.         else:  
  90.             count = self._cursor.execute(sql,param)  
  91.         if count>0:  
  92.             result = self._cursor.fetchmany(num)  
  93.         else:  
  94.             result = False  
  95.         return result  
  96.    
  97.     def insertOne(self,sql,value):  
  98.         """ 
  99.         @summary: 向数据表插入一条记录 
  100.         @param sql:要插入的SQL格式 
  101.         @param value:要插入的记录数据tuple/list 
  102.         @return: insertId 受影响的行数 
  103.         """  
  104.         self._cursor.execute(sql,value)  
  105.         return self.__getInsertId()  
  106.    
  107.     def insertMany(self,sql,values):  
  108.         """ 
  109.         @summary: 向数据表插入多条记录 
  110.         @param sql:要插入的SQL格式 
  111.         @param values:要插入的记录数据tuple(tuple)/list[list] 
  112.         @return: count 受影响的行数 
  113.         """  
  114.         count = self._cursor.executemany(sql,values)  
  115.         return count  
  116.    
  117.     def __getInsertId(self):  
  118.         """ 
  119.         获取当前连接最后一次插入操作生成的id,如果没有则为0 
  120.         """  
  121.         self._cursor.execute("SELECT @@IDENTITY AS id")  
  122.         result = self._cursor.fetchall()  
  123.         return result[0]['id']  
  124.    
  125.     def __query(self,sql,param=None):  
  126.         if param is None:  
  127.             count = self._cursor.execute(sql)  
  128.         else:  
  129.             count = self._cursor.execute(sql,param)  
  130.         return count  
  131.    
  132.     def update(self,sql,param=None):  
  133.         """ 
  134.         @summary: 更新数据表记录 
  135.         @param sql: SQL格式及条件,使用(%s,%s) 
  136.         @param param: 要更新的  值 tuple/list 
  137.         @return: count 受影响的行数 
  138.         """  
  139.         return self.__query(sql,param)  
  140.    
  141.     def delete(self,sql,param=None):  
  142.         """ 
  143.         @summary: 删除数据表记录 
  144.         @param sql: SQL格式及条件,使用(%s,%s) 
  145.         @param param: 要删除的条件 值 tuple/list 
  146.         @return: count 受影响的行数 
  147.         """  
  148.         return self.__query(sql,param)  
  149.    
  150.     def begin(self):  
  151.         """ 
  152.         @summary: 开启事务 
  153.         """  
  154.         self._conn.autocommit(0)  
  155.    
  156.     def end(self,option='commit'):  
  157.         """ 
  158.         @summary: 结束事务 
  159.         """  
  160.         if option=='commit':  
  161.             self._conn.commit()  
  162.         else:  
  163.             self._conn.rollback()  
  164.    
  165.     def dispose(self,isEnd=1):  
  166.         """ 
  167.         @summary: 释放连接池资源 
  168.         """  
  169.         if isEnd==1:  
  170.             self.end('commit')  
  171.         else:  
  172.             self.end('rollback');  
  173.         self._cursor.close()  
  174.         self._conn.close()  

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

[python] view plain copy print?
  1. #coding:utf-8  
  2. ''''' 
  3. Created on 2016年5月7日 
  4.  
  5. @author: baocheng 
  6. '''  
  7. DBHOST = "localhost"  
  8. DBPORT = 33606  
  9. DBUSER = "zbc"  
  10. DBPWD = "123456"  
  11. DBNAME = "test"  
  12. DBCHAR = "utf8"  
创建test模块,测试一下使用连接池进行mysql访问:

[python] view plain copy print?
  1. #coding:utf-8  
  2. ''''' 
  3.  
  4. @author: baocheng 
  5. '''  
  6. from MySqlConn import Mysql  
  7. from _sqlite3 import Row  
  8.   
  9. #申请资源  
  10. mysql = Mysql()  
  11.   
  12. 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"  
  13. result = mysql.getAll(sqlAll)  
  14. if result :  
  15.     print "get all"  
  16.     for row in result :  
  17.         print "%s\t%s"%(row["uid"],row["goodsname"])  
  18. 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"  
  19. result = mysql.getMany(sqlAll,2)  
  20. if result :  
  21.     print "get many"  
  22.     for row in result :  
  23.         print "%s\t%s"%(row["uid"],row["goodsname"])          
  24.           
  25.           
  26. result = mysql.getOne(sqlAll)  
  27. print "get one"  
  28. print "%s\t%s"%(result["uid"],result["goodsname"])  
  29.   
  30. #释放资源  
  31. mysql.dispose()  


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

  • dbapi :数据库接口
  • mincached :启动时开启的空连接数量
  • maxcached :连接池最大可用连接数量
  • maxshared :连接池最大可共享连接数量
  • maxconnections :最大允许连接数量
  • blocking :达到最大数量时是否阻塞
  • maxusage :单个连接最大复用次数
根据自己的需要合理配置上述的资源参数,以满足自己的实际需要。
至此,python中的mysql连接池实现完了,下次就直接拿来用就好了。
博客地址: data mining club