python实现数据库连接池

以下python代码实现了一个简单的数据库连接池,以sqlite3为例
class Pool(object):
    """一个数据库连接池"""

    def __init__(self, max_active=5, max_wait=None, init_size=0, db_type="SQLite3", **config):
        self.__freeConns = Queue(max_active)
        self.maxWait = max_wait
        self.db_type = db_type
        self.config = config
        if init_size > max_active:
            init_size = max_active
        for i in range(init_size):
            self.free(self._create_conn())

    def __del__(self):
        print("__del__ Pool..")
        self.release()

    def release(self):
        """释放资源,关闭池中的所有连接"""
        while self.__freeConns and not self.__freeConns.empty():
            con = self.get()
            con.release()
        self.__freeConns = None

    def _create_conn(self):
        """创建连接 """
        if self.db_type in dbcs:
            return dbcs[self.db_type](**self.config)

    def get(self, timeout=None):
        """获取一个连接
        @param timeout:超时时间
        """
        if timeout is None:
            timeout = self.maxWait
        conn = None
        if self.__freeConns.empty():  # 如果容器是空的,直接创建一个连接
            conn = self._create_conn()
        else:
            conn = self.__freeConns.get(timeout=timeout)
        conn.pool = self
        conn.row_factory = sqlite3.Row
        return conn

    def free(self, conn):
        """将一个连接放回池中
        @param conn: 连接对象
        """
        conn.pool = None
        if self.__freeConns.full():  # 如果当前连接池已满,直接关闭连接
            conn.release()
            return
        self.__freeConns.put_nowait(conn)


class PoolingConnection(object):
    __metaclass__ = ABCMeta

    def __init__(self, **config):
        self.conn = None
        self.config = config
        self.pool = None

    def __del__(self):
        self.release()

    def __enter__(self):
        pass

    def __exit__(self, exc_type, exc_value, traceback):
        self.close()

    def release(self):
        print("release PoolingConnection..")
        if self.conn is not None:
            self.conn.close()
            self.conn = None
        self.pool = None

    def close(self):
        if self.pool is None:
            raise PoolException("连接已关闭")
        self.pool.free(self)

    def __getattr__(self, val):
        if self.conn is None and self.pool is not None:
            self.conn = self._create_conn(**self.config)
        if self.conn is None:
            raise PoolException("无法创建数据库连接或连接已关闭")
        return getattr(self.conn, val)

    @abstractmethod    //定义一个抽象方法,该方法只有在子类中实例化才生效
    def _create_conn(self, **config):
        pass


class SQLit3PoolConnection(PoolingConnection):
    def _create_conn(self, **config):
        conn = sqlite3.connect(**config)
        conn.row_factory = sqlite3.Row
        return conn


dbcs = {"SQLite3": SQLit3PoolConnection}

pool = Pool(database=os.path.join(get_db_path(), "cluster.db3"))

在需要的地方调用该pool对象,
使用pool.get(5)获取一个conn对象
使用完成后务必关闭conn连接,因为sqlite不支持跨线程操作,若不关闭则可能会发生异常

以上代码只是一个简单的实现,有需要的童鞋可根据具体需求自行改造,希望对大家有帮助。

你可能感兴趣的:(python)