美文网首页
Python pymysql 封装 整合数据库连接池

Python pymysql 封装 整合数据库连接池

作者: 落花人独立_微雨燕双飞 | 来源:发表于2022-04-17 20:41 被阅读0次

    一、Python封装文件
    mysql_server.py

    #! /usr/bin/python
    # -*- coding: UTF-8 -*-
    
    import pymysql
    from dbutils.pooled_db import PooledDB
    from common.db.mysql_config import MysqlConfig
    
    """
        pymysql封装总结
        https://blog.csdn.net/zhj_1121/article/details/121070412
        
        python操作mysql之只看这篇就够了
        https://www.jianshu.com/p/4e72faebd27f
        
        关于PooledDB使用autocommit的方法
        https://blog.51cto.com/abyss/1736844
    """
    
    
    class MysqlPool:
        """
        MySQL 数据库连接池类 配置变量
        """
    
        '''
            :param
            reset: how connections should be reset when returned to the pool
                (False or None to rollback transcations started with begin(),
                True to always issue a rollback for safety's sake)
    
            :param 
            setsession: optional list of SQL commands that may serve to prepare
                the session, e.g. ["set datestyle to ...", "set time zone ..."]
        '''
    
        '''
            https://blog.51cto.com/abyss/1736844
            其中的
            setsession=['SET AUTOCOMMIT = 1']
            就是用来设置线程池是否打开自动更新的配置,0为False,1为True
        '''
    
        # 初始化数据库连接池变量
        __pool = None
    
        # 创建连接池的最大数量
        __MAX_CONNECTIONS = 100
        # 连接池中空闲连接的初始数量
        __MIN_CACHED = 10
        # 连接池中空闲连接的最大数量
        __MAX_CACHED = 20
        # 共享连接的最大数量
        __MAX_SHARED = 10
    
        # 超过最大连接数量时候的表现,为True等待连接数量下降,为false直接报错处理
        __BLOCK = True
        # 单个连接的最大重复使用次数
        __MAX_USAGE = 100
    
        # 当返回到池时,连接应该如何重置
        # (False或None回滚以begin()开始的事务,为了安全起见,总是发出回滚)
        __RESET = True
        # 设置自动提交
        __SET_SESSION = ['SET AUTOCOMMIT = 1']
    
        # 不能是 UTF-8
        __CHARSET = 'UTF8'
    
        def __init__(self, host, port, user, password, database):
            """
            :param host: 数据库主机地址
            :param port: 端口号
            :param user: 用户名
            :param password: 密码
            :param database: 数据库名
            """
            if not self.__pool:
                # self代表当前类的实例,即为 MysqlPool() 带小括号,执行后的数据。
                # __class__,魔法函数,代表从当前类的实例中,获取当前类,即为 MysqlPool 不带小括号的类。
                # __pool,这个代表的事类的变量,即为在类下面创建的初始化连接池,__pool
                self.__class__.__pool = PooledDB(
                    creator=pymysql,
                    host=host,
                    port=port,
                    user=user,
                    password=password,
                    database=database,
    
                    maxconnections=self.__MAX_CONNECTIONS,
                    mincached=self.__MIN_CACHED,
                    maxcached=self.__MAX_CACHED,
                    maxshared=self.__MAX_SHARED,
    
                    blocking=self.__BLOCK,
                    maxusage=self.__MAX_USAGE,
                    setsession=self.__SET_SESSION,
                    reset=self.__RESET,
    
                    charset=self.__CHARSET
                )
    
        def get_connect(self):
            return self.__pool.connection()
    
    
    class MysqlCursor:
        """
        从数据库配置环境,取出数据库配置参数
        这里的参数,可以不从外部导入,直接手动写入也可以。
        """
        host = MysqlConfig().current_config()[0]
        port = MysqlConfig().current_config()[1]
        user = MysqlConfig().current_config()[2]
        password = MysqlConfig().current_config()[3]
        database = MysqlConfig().current_config()[4]
    
        def __init__(self, host=host, port=port, user=user, password=password, database=database) -> None:
            """
            :param host: 数据库主机地址
            :param port: 端口号
            :param user: 用户名
            :param password: 密码
            :param database: 数据库名
            """
            self.__host = host
            self.__port = port
            self.__user = user
            self.__password = password
            self.__database = database
    
            # 初始化数据库连接池
            self.connects_pool = MysqlPool(
                host=self.__host,
                port=self.__port,
                user=self.__user,
                password=self.__password,
                database=self.__database
            )
    
        def __enter__(self):
            """
            # with 上下文管理,魔法函数,进入with时调用
            :return: 当前类
            """
            # 从数据库链接池,获取一个数据库链接
            connect = self.connects_pool.get_connect()
            # 从获取的数据库链接,获取一个光标
            cursor = connect.cursor(pymysql.cursors.DictCursor)
    
            '''
            # https://blog.51cto.com/abyss/1736844
            # 如果使用连接池 则不能在取出后设置 而应该在创建线程池时设置
            # connect.autocommit = False 
            '''
            # 将数据库链接,赋值给当前类,方便__exit__函数调用
            self._connect = connect
            # 将数据库光标,赋值给当前类,方便__exit__函数调用
            self._cursor = cursor
    
            # __enter__函数,必须返回当前类
            return self
    
        def __exit__(self, *exc_info):
            """
            # with 上下文管理,魔法函数,退出with时调用
            :param exc_info: 异常信息,元祖
            :return: None
            """
            # 退出with上下文时,使用当前类链接,提交数据库语句
            self._connect.commit()
            # 关闭光标
            self._cursor.close()
            # 关闭链接
            self._connect.close()
    
        @property
        def cursor(self):
            """
            数据库连接池,取出链接,取出光标,转换为光标属性
            :return: 数据库连接池的光标
            """
            return self._cursor
    
    
    if __name__ == "__main__":
    
        with MysqlCursor() as db:
            # 获取数据库的方法
            sql = 'select count(id) as total from people'
            db.cursor.execute("select count(id) as total from people")
            data = db.cursor.fetchone()
            print('--------统计数据条数', data)
    
    

    相关文章

      网友评论

          本文标题:Python pymysql 封装 整合数据库连接池

          本文链接:https://www.haomeiwen.com/subject/vhnlertx.html