pymysql通过DBUtils实现连接池技术

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

一、安装

pip install DBUtils

二、导入模块

# 针对不同版本,可能导入方式存在差别
try:
    from dbutils.pooled_db import PooledDB
    from dbutils.persistent_db import PersistentDB
except:
    from DBUtils.PooledDB import PooledDB
    from DBUtils.PersistentDB import PersistentDB

三、使用

  • DBUtils提供两种外部接口:

    • PersistentDB:

      • 每当一个线程首次打开数据库连接时,都会创建一个新的数据库连接,并且该连接始终服务于该特定线程,直到该线程销毁,连接才会关闭
      • 通过重用数据库连接来提高数据库的访问性能,同时确保了线程间不共享数据库连接(当线程数一定的情况下,推荐使用
      • 注意:避免短时间内创建多个线程(创建多个线程时,可使用延时操作)
      • 实例化时常用参数设置:
        import pymysql
        from dbutils.persistent_db import PersistentDB
        
        pool = PersistentDB(pymysql, host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER, db=MYSQL_DATABASE, password=MYSQL_PASSWORD, charset='utf8mb4')

        第一个参数指定的是连接数据库的模块pymysql,其它使用默认参数(maxusage=None或者0表示每个连接的使用次数不受限,ping=1表示每次获取连接时,检查连接是否可用...),后面都是使用pymysql中的参数

      • 示例
        import time
        
        import pymysql
        import threading
        from dbutils.persistent_db import PersistentDB
        from sc.common.config import *
        
        pool = PersistentDB(pymysql, host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER, db=MYSQL_DATABASE, password=MYSQL_PASSWORD, charset='utf8mb4')
        id_set = set() # 统计连接池中的连接数
        def test():
            for i in range(100):
                con = pool.connection()
                id_set.add(id(con))
                con.close()
        
        # 创建5个子线程
        t_list = []
        for i in range(5):
            t = threading.Thread(target=test)
            t_list.append(t)
            t.start()
            time.sleep(0.2) # 延时操作
        
        for t in t_list:
            t.join()
        
        # 主线程操作
        test()
        print(id_set) # 总共6个线程(1主+5子),6个连接:{1779330541312, 1779330540064, 1779330275744, 1779330276896, 1779330331120, 1779330276944}
    • PooledDB

      • 能够提供线程间可共享的数据库连接,但是需要通过maxshared参数指定最多可共享连接数
      • 对于应用中需要频繁地创建和销毁线程时,推荐使用
      • 实例化常用参数设置:
        import pymysql
        from dbutils.pooled_db import PooledDB
        
        pool = PooledDB(pymysql, maxconnections=10, blocking=True, host=MYSQL_HOST, port=MYSQL_PORT, user=MYSQL_USER, db=MYSQL_DATABASE, password=MYSQL_PASSWORD, charset='utf8mb4')

        参数:

        mincached:初始时连接池中的连接数,默认为0。
        maxcached:连接池中最大的闲置连接数,默认为0表示不限制。
        maxconnections:连接池允许的最大连接数,默认为0表示不限制。
        blocking:当连接池达到最大连接数并且所有连接都在使用中时,是否阻塞等待可用连接,默认为False。
        maxusage:单个连接的最大重复使用次数,默认为0表示不限制
      • 示例(待补充)
  • 使用连接池操作数据库

    con = pool.connection() # 从池中获取数据库连接
    cursor = con.cursor() # 创建游标
    sql = '比如插入相关的sql语句'
    try:
        cursor.execute(sql, [])
        con.commit()
    except:
        con.rollback()
    finally:
        cursor.close() # 关闭游标
        con.close() # 将数据库连接放回连接池(注意不是关闭该连接)

    连接池pool最后不需要我们手动调用close()方法关闭,内部帮我们自动维护(__del__()方法中已实现self.close())

posted @ 2023-02-22 01:16  eliwang  阅读(586)  评论(0编辑  收藏  举报