Python mysql连接池

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

python的数据库连接池包 DBUtils:

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

DBUtils提供两种外部接口:
  • * PersistentDB :提供线程专用的数据库连接,并自动管理连接。
  • * PooledDB :提供线程间可共享的数据库连接,并自动管理连接。

需要的python库: 下载DBUtils: Webware 的网站下载最新版本:http://www.webwareforpython.org/downloads/DBUtils/ 或者在Python Package Index来下载:http://www.python.org/pypi/DBUtils/ 下载pymssql: http://code.google.com/p/pymssql/downloads/list (pymssql 是Python语言用来连接微软 SQL SERVER 数据库的类库) 1.写一个创建连接池,获取连接以及重新连接数据库的模块:

    # libby_db_pool.py
    # 代码如下:
    #-*- coding:utf-8 -*-
    from DBUtils.PooledDB import PooledDB
    import pymssql #sqlserver数据库适配器
    from pymssql import OperationalError, InternalError, ProgrammingError
    HOST = "127.0.0.1"
    PORT = "1433"
    CHARSET = "utf8"
    NAME = "zkeco_oracle"
    USER = "sa"
    PASSWORK = "sa"
    conn_args = {
        'host':"%s"%HOST,
        'port':"%s"%PORT,
        'database':"%s"%NAME,
        'charset':"%s"%CHARSET,
        'user':"%s"%USER,
        'password':"%s"%PASSWORK
    }
    """
        mincached : 启动时开启的闲置连接数量(缺省值 0 以为着开始时不创建连接)
        maxcached : 连接池中允许的闲置的最多连接数量(缺省值 0 代表不闲置连接池大小)
        maxshared : 共享连接数允许的最大数量(缺省值 0 代表所有连接都是专用的)如果达到了最大数量,被请求为共享的连接将会被共享使用
        maxconnecyions : 创建连接池的最大数量(缺省值 0 代表不限制)
        blocking : 设置在连接池达到最大数量时的行为(缺省值 0 或 False 代表返回一个错误<toMany......>; 其他代表阻塞直到连接数减少,连接被分配)
        maxusage : 单个连接的最大允许复用次数(缺省值 0 或 False 代表不限制的复用).当达到最大数时,连接会自动重新连接(关闭和重新打开)
        setsession : 一个可选的SQL命令列表用于准备每个会话,如["set datestyle to german", ...]
    """
    args = (10,10,30,100,True,0,None)
    class DbManager():
        def __init__(self):
            try:
                self._pool = PooledDB(pymssql,*args,**conn_args)
            except Exception,e:
                print "The parameters for DBUtils is:",conn_args
        def _getConn(self):
            return self._pool.connection()
    _dbManager = DbManager()
    def getConn():
        """ 获取数据库连接 """
        return _dbManager._getConn()
    def _reConn():
        """ 重新连接数据库 """
        global _dbManager
        re = False
        try:
            _dbManager = DbManager()
            re = True
        except:
            import traceback
            traceback.print_exc()
        finally:
            return re
    import datetime
    def reConn():
        print "%s: now try to reconnect Database!"%(datatime.datatime.now())
        flag = _reConn()
        if flag:
            print "%s reconnect database success!"%(datatime.datatime.now())
        else:
            print "%s reconnect database failed!"%(datatime.datatime.now())

2.写一个支持增删查改功能的连接池模块:

    #libby_sql_utils.py
    #代码如下:
    #-*- coding:utf-8 -*-
    from libby_db_pool import getConn,reConn
    from libby_db_pool import OperationalError, InternalError, ProgrammingError
    import traceback
    def test_conn():
        """
            测试连接池连接是否正常
            return:
            res:True:正常,False:不正常
            msg:如果不正常,为异常信息
        """
        test_sql = """
            select 1
        """
        conn = None
        cur = None
        res = False
        msg = ""
        try:
            conn = getConn()
            cur = conn.cursor()
            cur.execute(test_sql)
            res = cur.fetchall()
            res = True
        except Exception,e:
            trackback.print_exc()
            msg = e
        finally:
            if cur:
                cur.close()
            if conn:
                conn.close()
            return res,msg
    def call_reConn():
        """
            重新创建连接池
        """
        reConn()
    def p_query(sql):
        """
            dbutils 数据连接池
                只能执行数据查询sql语句,否则会抛错
            @parm: 要执行的sql语句
            @return:
                []:查询结果为空
                None:sql语句执行失败,出现异常
                        二维list:正常结果
        """
        conn = None
        cur = None
        res = None
        try:
            conn = getConn()
            cur = conn.cursor()
            cur.execute(sql)
            res = cur.fetchall()
        except (OperationalError, InternalError):
            call_reConn()
            trackback.print_exc()
        except:
            trackback.exc()
        finally:
            if cur:
                cur.close()
            if conn:
                conn.close()
            return res
    def p_query_one(sql):
        """
            dbutils 数据连接池
                    只能执行数据查询sql语句,否则会报错
                    执行sql查询语句,获取第一条记录
            @parm:要执行的sql语句
            @return:
                []:查询结果为空
                None:sql语句执行失败,出现异常
                list:正常结果
        """
        conn = None
        cur = None
        res = None
        try:
            conn = getConn()
            cur = conn.cursor()
            cur.execute(sql)
            res = cur.fetchone()
        except (OperationalError,InternalError):
            call_reConn()
        except:
            traceback.print_exc()
        finally:
            if cur:
                cur.close()
            if conn:
                conn.close()
            return res
    def p_execute(sql):
        """
            dbutils 数据连接池
                    执行数据操作语句,包括 update,insert,delete
            @parm:要执行的sql
            @return:
                None:sql语句执行失败,出现异常
                number:影响记录条数
                -2:数据库连接失败导致执行失败
        """
        conn = None
        cur = None
        res = None
        try:
            conn = getConn()
            cur = conn.cursor()
            cur.execute(sql)
            res = cur._cursor.rowcount
            conn.commit()
        except Exception,e:
            if conn:
                conn.rollback()
            traceback.print_exc()
        finally:
            if res == -1:#可能是数据库断开连接
                ret,msg = test_conn()
                if not ret:
                    call_reConn()
                    res = -2
            if cur:
                cur.close()
            if conn:
                conn.close()
            return res
    def p_mutiexec(sql_list):
        """
            dbutils 数据连接池
                    执行多条数据操作语句,可以用于多条sql语句的事务性操作,包括 update,insert,delete
            @parm:要执行的sql语句[]
            @return:
                (flag,res):
                    flag<Ture or False>:批次是否全部执行成功
                    res<list>:每天sql语句执行影响的行数,如果执行失败,由此可以判断第几条sql语句执行失败
                                如果遇到数据库断开的情况,返回[-2,]
        """
        conn = None
        cur = None
        res = []
        flag = True
        try:
            conn = getConn()
            cur = conn.cursor()
            for sql in sql_list:
                cur.execute(sql)
                num = cur._cursor.rowcount
                res.append(num)
            conn.commit()
        except Exception,e:
            if conn:
                conn.rollback()
            traceback.print_exc()
        finally:
            if -1 in res:
                ret,msg = test_conn()
                if not ret:
                    call_reConn()
                    flag = False
                    res = [-2,]
            if cur:
                cur.close()
            if conn:
                conn.close()
            return flag,res

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

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

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

本文分享自微信公众号 - 编程坑太多(idig88)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-03-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏MasiMaro 的技术博文

OLEDB 数据变更通知

除了之前介绍的接口,OLEDB还定义了其他一些支持回调的接口,可以异步操作OLEDB对象或者得到一些重要的事件通知,从而使应用程序有机会进行一些必要的处理。其中...

12630
来自专栏Jerry的SAP技术分享

C4C Cloud Application Studio做ABSL开发的一些性能方面的最佳实践

Stefan Hagen在博文SAP Cloud Application Studio Performance Best Practices里介绍了在C4C里使...

21980
来自专栏JavaEE

Java面试题 - 03前言:三、框架篇:

1. JDBC编程有什么不足?mybatis是如何解决的? 答:主要有以下几个方面:

11410
来自专栏漏斗社区

大数据搜索引擎之elasticsearch使用篇(一)

在上一篇文章《大数据搜索分析引擎elasticsearch(安装篇)》中,斗哥介绍了elasticsearch的基本安装过程,本期,我们将着重介绍elastic...

38440
来自专栏hbbliyong

在C#使用文件监控对象FileSystemWatcher 实现数据同步

       最近在项目中有这么个需求,就是得去实时获取某个在无规律改变的文本文件中的内容。首先想到的是用程序定期去访问这个文件,因为对实时性要求很高,间隔不能...

45060
来自专栏c#开发者

Msmq设计文档(赋源代码)

Msmq设计文档 文件状态: [√] 草稿 [ ] 正式发布 [ ] 正在修改 文件标识: ECI-MSMQ v01 当前版本: 0.5...

36880
来自专栏13blog.site

Spring+SpringMVC+MyBatis+easyUI整合基础篇(八)mysql中文查询bug修复

前言   在测试搜索时出现的问题,mysql通过中文查询条件搜索不出数据,但是英文和数字可以搜索到记录,中文无返回记录。本文就是写一下发现问题的过程及解决方法...

36050
来自专栏熊训德的专栏

Hbase compaction 源码分析一:compaction 概况分析

本文档从框架的源码角度梳理了,hbase 在什么情况下会触发compaction,并通过官方文档说明出发minor 和major compaction的时间点。

56810
来自专栏人工智能LeadAI

mongoDB的安装及基本使用

mongoDB简介 1、NoSQL数据库 数据库:进行高效的、有规则的进行数据持久化存储的软件 NoSQL数据库:Not only sql,指代非关系型数据库...

31980
来自专栏salesforce零基础学习

salesforce零基础学习(八十六)Ajax Toolkit (VF页面中使用及javascript action使用)

Ajax Toolkit 参考文档:https://resources.docs.salesforce.com/212/latest/en-us/sfdc/pd...

32660

扫码关注云+社区

领取腾讯云代金券