Python實現(xiàn)Mysql數(shù)據(jù)庫連接池

Python實現(xiàn)Mysql數(shù)據(jù)庫連接池

python連接Mysql數(shù)據(jù)庫:

python編程中可以使用MySQLdb進行數(shù)據(jù)庫的連接及諸如查詢/插入/更新等操作,但是每次連接mysql數(shù)據(jù)庫請求時,都是獨立的去請求訪問,相當浪費資源,而且訪問數(shù)量達到一定數(shù)量時,對mysql的性能會產(chǎn)生較大的影響。因此,實際使用中,通常會使用數(shù)據(jù)庫的連接池技術(shù),來訪問數(shù)據(jù)庫達到資源復用的目的。

數(shù)據(jù)庫連接池

python的數(shù)據(jù)庫連接池包 DBUtils:

DBUtils是一套Python數(shù)據(jù)庫連接池包,并允許對非線程安全的數(shù)據(jù)庫接口進行線程安全包裝。DBUtils來自Webware for Python。

DBUtils提供兩種外部接口:

* PersistentDB :提供線程專用的數(shù)據(jù)庫連接,并自動管理連接。
* PooledDB :提供線程間可共享的數(shù)據(jù)庫連接,并自動管理連接。

下載地址:DBUtils 下載解壓后,使用python setup.py install 命令進行安裝

下面利用MySQLdb和DBUtils建立自己的mysql數(shù)據(jù)庫連接池工具包

在工程目錄下新建package命名為:dbConnecttion,并新建module命名為MySqlConn,下面是MySqlConn.py,該模塊創(chuàng)建Mysql的連接池對象,并創(chuàng)建了如查詢/插入等通用的操作方法。該部分代碼實現(xiàn)如下:

# -*- coding: UTF-8 -*-
"""
Created on 2016年5月7日

@author: baocheng
1、執(zhí)行帶參數(shù)的SQL時,請先用sql語句指定需要輸入的條件列表,然后再用tuple/list進行條件批配
2、在格式SQL中不需要使用引號指定數(shù)據(jù)類型,系統(tǒng)會根據(jù)輸入?yún)?shù)自動識別
3、在輸入的值中不需要使用轉(zhuǎn)意函數(shù),系統(tǒng)會自動處理
"""

import MySQLdb
from MySQLdb.cursors import DictCursor
from DBUtils.PooledDB import PooledDB
#from PooledDB import PooledDB
import Config

"""
Config是一些數(shù)據(jù)庫的配置文件
"""

class Mysql(object):
    """
    MYSQL數(shù)據(jù)庫對象,負責產(chǎn)生數(shù)據(jù)庫連接 , 此類中的連接采用連接池實現(xiàn)獲取連接對象:conn = Mysql.getConn()
            釋放連接對象;conn.close()或del conn
    """
    #連接池對象
    __pool = None
    def __init__(self):
        #數(shù)據(jù)庫構(gòu)造函數(shù),從連接池中取出連接,并生成操作游標
        self._conn = Mysql.__getConn()
        self._cursor = self._conn.cursor()

    @staticmethod
    def __getConn():
        """
        @summary: 靜態(tài)方法,從連接池中取出連接
        @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: 執(zhí)行查詢,并取出所有結(jié)果集
        @param sql:查詢SQL,如果有查詢條件,請只指定條件列表,并將條件值使用參數(shù)[param]傳遞進來
        @param param: 可選參數(shù),條件列表值(元組/列表)
        @return: result list(字典對象)/boolean 查詢到的結(jié)果集
        """
        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: 執(zhí)行查詢,并取出第一條
        @param sql:查詢SQL,如果有查詢條件,請只指定條件列表,并將條件值使用參數(shù)[param]傳遞進來
        @param param: 可選參數(shù),條件列表值(元組/列表)
        @return: result list/boolean 查詢到的結(jié)果集
        """
        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: 執(zhí)行查詢,并取出num條結(jié)果
        @param sql:查詢SQL,如果有查詢條件,請只指定條件列表,并將條件值使用參數(shù)[param]傳遞進來
        @param num:取得的結(jié)果條數(shù)
        @param param: 可選參數(shù),條件列表值(元組/列表)
        @return: result list/boolean 查詢到的結(jié)果集
        """
        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: 向數(shù)據(jù)表插入一條記錄
        @param sql:要插入的SQL格式
        @param value:要插入的記錄數(shù)據(jù)tuple/list
        @return: insertId 受影響的行數(shù)
        """
        self._cursor.execute(sql,value)
        return self.__getInsertId()

    def insertMany(self,sql,values):
        """
        @summary: 向數(shù)據(jù)表插入多條記錄
        @param sql:要插入的SQL格式
        @param values:要插入的記錄數(shù)據(jù)tuple(tuple)/list[list]
        @return: count 受影響的行數(shù)
        """
        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: 更新數(shù)據(jù)表記錄
        @param sql: SQL格式及條件,使用(%s,%s)
        @param param: 要更新的  值 tuple/list
        @return: count 受影響的行數(shù)
        """
        return self.__query(sql,param)

    def delete(self,sql,param=None):
        """
        @summary: 刪除數(shù)據(jù)表記錄
        @param sql: SQL格式及條件,使用(%s,%s)
        @param param: 要刪除的條件 值 tuple/list
        @return: count 受影響的行數(shù)
        """
        return self.__query(sql,param)

    def begin(self):
        """
        @summary: 開啟事務
        """
        self._conn.autocommit(0)

    def end(self,option='commit'):
        """
        @summary: 結(jié)束事務
        """
        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,包括數(shù)據(jù)庫的連接信息/用戶名密碼等:

#coding:utf-8
'''
Created on 2016年5月7日

@author: baocheng
'''
DBHOST = "localhost"
DBPORT = 33606
DBUSER = "zbc"
DBPWD = "123456"
DBNAME = "test"
DBCHAR = "utf8"

創(chuàng)建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()

當然,還有很多其他參數(shù)可以配置:

dbapi :數(shù)據(jù)庫接口
mincached :啟動時開啟的空連接數(shù)量
maxcached :連接池最大可用連接數(shù)量
maxshared :連接池最大可共享連接數(shù)量
maxconnections :最大允許連接數(shù)量
blocking :達到最大數(shù)量時是否阻塞
maxusage :單個連接最大復用次數(shù) 根據(jù)自己的需要合理配置上述的資源參數(shù),以滿足自己的實際需要。

至此,python中的mysql連接池實現(xiàn)完了,下次就直接拿來用就好了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容