自定义MongoDB连接池

时间:2022-09-19 23:44:31
# Copyright 2017-2020 Mark
#
# This is the first time taht I try to create wheel use python

# depends on module MongoClient from pymongo

"""
MongoDB连接池模块
"""

from pymongo import MongoClient


class MongoPool(object):
"""
MongoDB连接池
复习了默认参数数的用法和自定义异常
子类调用父类构造函数super(子,self).__init__(*args)
isinstance(max_conn, int)的用法
"""


def __init__(self, uri, max_conn=30):
"""
:param max_conn: 最大连接数 默认30 必须是1到200之间的整数
:param uri: 数据库连接uri mongodb://username:password@localhost:27017
"""


# 如果max_conn为空或者不是1到200之间的整数 抛出异常
if not max_conn or not isinstance(max_conn, int) or max_conn > 200 or max_conn < 1:
raise MongoPoolInitException(errorMsg='客官,max_conn不可以等于{}哦'.format(max_conn))
self.__max_conn = max_conn
self.__conn_list = []
self.__uri = uri
self.__idle = self.__max_conn
self.__busy = 0
self.__prepare_conn()

def __prepare_conn(self):
"""
根据参数max_conn初始化连接池
:return: None
"""

try:
for x in range(0, self.__max_conn):
conn_dict = {'conn': MongoClient(self.__uri), 'busy': False}
self.__conn_list.append(conn_dict)
except Exception as e:
raise MongoPoolException('Bad uri: {}'.format(self.__uri))

def get_conn(self):
"""
从连接池中获取一个MongoDB连接对象
:return: mongodb_connection
"""

if self.__idle < 1:
raise MongoPoolOutOfConnections(errorMsg='不好啦!Mongo的连接数不够用了!')
for index in range(0, len(self.__conn_list)):
conn = self.__conn_list[index]
if conn.get('busy') == False:
conn['busy'] = True
self.__busy += 1
self.__idle -= 1
return conn.get('conn')

def close(self, conn):
"""
将参数中的连接池对象的busy改为False,标识此连接为空闲状态
:param conn: mongoDB数据库连接对象
:return: None
"""

for index in range(0, len(self.__conn_list)):
inner_conn = self.__conn_list[index]
if inner_conn.get('conn') == conn:
inner_conn['busy'] = True
self.__busy -= 1
self.__idle += 1
inner_conn['busy'] = False
break
else:
raise MongoPoolException("你特么的在逗我呢!这个连接不是从我这借的,我不要!")


class MongoPoolInitException(Exception):
"""
初始化异常
"""


def __init__(self, errorMsg):
super(MongoPoolInitException, self).__init__(errorMsg)


class MongoPoolOutOfConnections(Exception):
"""
连接数不够用了
"""


def __init__(self, errorMsg):
super(MongoPoolOutOfConnections, self).__init__(errorMsg)


class MongoPoolException(Exception):
"""
MongoPool其他异常
"""


def __init__(self, errorMsg):
super(MongoPoolException, self).__init__(errorMsg)

# init.py中的__all__
# 限制可被导入的模块需要注意的是 __all__ 只影响到了 from <module> import * 这种导入方式,
# 对于 from <module> import <member> 导入方式并没有影响,仍然可以从外部导入。
# __slots__类级别的限制 在模块中用 限制可被动态添加的属性 可这种限制可被继承和覆盖
# 给类动态绑定的属性是不会被继承的
# 类方法和属性私有化 __methodname() __var
# 类变量前加 __并不能起到私有化的作用 会被动态绑定新的属性