我的编程空间,编程开发者的网络收藏夹
学习永远不晚

python自制简易mysql连接池的实现示例

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

python自制简易mysql连接池的实现示例

今天我们来说一点不一样的, 使用python语言手撸mysql连接池.

连接池是什么?

连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。在并发量足够时连接池一般比直接连接性能更优, 不仅提高了性能的同时还管理了宝贵的资源.

为什么需要连接池?

讨论这个问题时, 我们需要先了解高并发导致服务器卡顿的原因出在哪里.

正常情况下, 每当一位用户使用各类终端连接到服务器的时候, 服务器都需要开辟一片内存为其服务, 每当一个请求从前端传入都需在mysql之间创建一条连接. 然而过多的连接会导致服务器卡顿内存占用过高, 这时候就需要连接池对所有连接状态进行管理, 合理分配&回收资源.

简单说就是使用连接池技术可用减少服务器压力.

连接池的原理是什么?

连接池主要需要两个参数,默认连接数、最大连接数

  • 当服务启动时, 首先创建默认连接数的空闲连接放入池中.
  • 当用户需要连接时, 首先查看池中是否有空闲连接.
    • 如果有: 由连接池分配从池中取出一个空闲连接交付用户使用.
    • 如果没有: 查看当前存活的所有连接总数是否大于最大连接.
      • 如果小于: 创建新连接交付用户使用.
      • 如果等于: 线程阻塞, 等待有空闲连接再交予用户.
  • 当用户用完连接后, 查看当前存活连接数是否大于默认值.
  • 如果小于等于: 将此条连接重新放入空闲池中, 等待下一次使用.
  • 如果大于: 将此条连接释放销毁, 不放入池中.

使用python语言自制简易mysql连接池

这里, 我们需要 ThemisPool.py 连接池本身, db.cnf 配置文件, 其目录路径如下:


# 推荐目录格式, ThemisPool.py & db.cnf 只需要在同级目录下即可
[your python project]
    |
    |
    |-- util
         |
         |-- db.cnf
         |
         |-- ThemisPool.py

ThemisPool.py


# 导入依赖
# mysql连接基本库
import pymysql

# 读取配置文件所需要的库
import configparser
import os

# 线程管理所需要的库
import threading


# 创建配置类用户读取配置文件
class Config(object):
    def __init__(self, configFileName='db.cnf'):
        file = os.path.join(os.path.dirname(__file__), configFileName)
        self.config = configparser.ConfigParser()
        self.config.read(file)

    def getSections(self):
        return self.config.sections()

    def getOptions(self, section):
        return self.config.options(section)

    def getContent(self, section):
        result = {}
        for option in self.getOptions(section):
            value = self.config.get(section, option)
            result[option] = int(value) if value.isdigit() else value
        return result
 
# 将连接所需要的参数封装在对象中 
# 依次为: 数据库密码、需要连接的库名、主机地址[默认 localhost]、端口号[默认 3306]、初始化连接数[默认 3]、最大连接数[默认 6]
class parameter(object):
    def __init__(self, password, database, host="localhost",port="3306" user="root", initsize=3, maxsize=6):
        self.host = str(host)
        self.port = int(port)
        self.user = str(user)
        self.password = str(password)
        self.database = str(database)
        self.maxsize = int(maxsize)
        self.initsize = int(initsize)

# 连接池
class ThemisPool(parameter):
    def __init__(self, fileName='db.cnf', configName='mysql'):
        # 加载配置文件, 配置文件名默认为 'db.cnf', 配置标签默认为 'mysql'
        self.config = Config(fileName).getContent(configName)
        super(ThemisPool, self).__init__(**self.config)
        # 创建队列作为 池
        self.pool = queue.Queue(maxsize=self.maxsize)
        self.idleSize = self.initsize
        # 创建线程锁
        self._lock = threading.Lock()
        # 初始化连接池
        for i in range(self.initsize):
            # 创建 初始化连接数 数量的连接放入池中
            self.pool.put(self.createConn())
        # 启动日志
        print('\033[1;32m ThemisPool connect database {database}, login is {user} \033[0m'.format(database=self.database,
                                                                                 user=self.user))
                                                                          
    # 生产连接
    def createConn(self):
        # 使用mysql基本类 
        # pymysql.connect 参数这里不做解释,具体请查阅官网 https://pypi.org/project/PyMySQL/
        return pymysql.connect(host=self.host,
                               port=self.port,
                               user=self.user,
                               password=self.password,
                               database=self.database,
                               charset='utf8')
    
    # 获取连接
    def getConn(self):
        self._lock.acquire()
        try:
            # 如果池中连接够直接获取
            if not self.pool.empty():
                self.idleSize -= 1
            else:
                # 否则重新添加新连接
                if self.idleSize < self.maxsize:
                    self.idleSize += 1
                    self.pool.put(self.createConn())
        finally:
            self._lock.release()
            return self.pool.get()
     
    # 释放连接
    def releaseCon(self, conn=None):
        try:
            self._lock.acquire()
            # 如果池中大于初始值就将多余关闭,否则重新放入池中
            if self.pool.qsize() < self.initsize:
                self.pool.put(conn)
                self.idleSize += 1
            else:
                try:
                    # 取出多余连接并关闭
                    surplus = self.pool.get()
                    surplus.close()
                    del surplus
                    self.idleSize -= 1
                except pymysql.ProgrammingError as e:
                    raise e
        finally:
            self._lock.release()
      
      
    # 拉取数据(查询)
    # 可用语句类型 (select)
    def fetchone(self, sql):
        themis = None
        cursor = None
        try:
            themis = self.getConn()
            cursor = themis.cursor()
            cursor.execute(sql)
            return cursor.fetchall()
        except pymysql.ProgrammingError as e:
            raise e
        except pymysql.OperationalError as e:
            raise e
        except pymysql.Error as e:
            raise e
        finally:
            cursor.close()
            self.releaseCon(themis)
     
    # 更新
    # 可用语句类型 (insert, update, delete)
    def update(self, sql):
        themis = None
        cursor = None
        try:
            themis = self.getConn()
            cursor = themis.cursor()
            cursor.execute(sql)
            return cursor.lastrowid
        except pymysql.ProgrammingError as e:
            raise e
        except pymysql.OperationalError as e:
            raise e
        except pymysql.Error as e:
            raise e
        finally:
            themis.commit()
            cursor.close()
            self.releaseCon(themis)
            
     # 释放连接池本身
     def __del__(self):
        try:
            while True:
                conn = self.pool.get_nowait()
            if conn:
                conn.close()
        except queue.Empty:
            pass

db.cnf 配置文件


[mysql]
host = localhost
user = root
password = 12345678
database = practice
initsize = 3
maxsize = 6

所有配置属性

参数 说明 类型 默认值
host 主机地址 str localhost
port 端口号 int 3306
user mysql登录用户名 str root
password mysql登录密码 str -
database 访问库名 str -
initsize 初始化连接数 int 3
maxsize 最大连接数 int 6

开始使用


from util.ThemisPool import ThemisPool

# 初始化ThemisPool连接池 (Initialize the ThemisPool connection pool)
db = ThemisPool()

# 查询拉取数据,函数会直接返回数据 (Query pull data.It returns data directly)
selectSql = "select * from user;"
data = db.fetchone(selectSql)

# 增、删、改语句, 如果有使用mysql自增长插入的值函数会返回自增长的数据 (insert,upate delete and alter. If there is a value function inserted using mysql self-growth, it will return self-growth data)
insertSql = "insert into user values(null,'user001','123456')"
id = db.update(selectSql)

自定义配置文件名 & 配置标签

配置文件名默认为 db.cnf, 配置标签默认为 [mysql]

例如自定义配置文件名为 myDB.cnf, 配置标签为 [mysqlConfig]


# myDB.cnf

[mysqlConfig]
host = localhost
user = root
password = 12345678
database = practice
initsize = 3
maxsize = 6

# 使用时
...
db = ThemisPool(fileName='myDB.cnf', configName='mysqlConfig')
...

命名思路

Themis(忒弥斯) 取名来自于古希腊神话中秩序女神的名字, 就如同连接池的作用一样, 管理所有用户的连接, 减少不必要的损耗。

GitHub地址

ThemisPool连接池

以上就是本次的全部内容, 下版本将会解决 python 不能对 datetime 类型的数据进行 json格式化 的问题, 并将它集成进来

到此这篇关于python自制简易mysql连接池的实现示例的文章就介绍到这了,更多相关python mysql连接池内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

python自制简易mysql连接池的实现示例

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

python自制简易mysql连接池的实现方法是什么

这篇文章主要讲解了“python自制简易mysql连接池的实现方法是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“python自制简易mysql连接池的实现方法是什么”吧!连接池是什么?
2023-06-25

jdbc中自带MySQL 连接池实践示例

引言在上期文章自定义 mysql 连接池中,我提到了没找到一个特别合适的 MySQL 连接池实现,所以自己写了一个基于通用池化框架commons-pool2的 MySQL 连接池,并且模仿了 Go 语言的gorm框架设计思路,把借和还的操
2022-07-21

MySQL实现自然连接查询的示例

目录什么是自然连接?如何使用自然连接?自然连接的注意事项自然连接的缺点类似的连接方式总结mysql是一种流行的关系型数据库管理系统,其强大的查询功能是其受欢迎的原因之一。在MySQL中,有多种查询方式可以检索和组合不同的表中的数据。其中之一
MySQL实现自然连接查询的示例
2024-09-19

php7连接MySQL制作简易查询程序的案例

这篇文章主要介绍php7连接MySQL制作简易查询程序的案例,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!PHP: config.php 存放数据库配置信息 cx.php 查询程序 index.html 用户界面推荐
2023-06-14

Python实现Mysql数据库连接池实例详解

python连接Mysql数据库:Python编程中可以使用MySQLdb进行数据库的连接及诸如查询/插入/更新等操作,但是每次连接MySQL数据库请求时,都是独立的去请求访问,相当浪费资源,而且访问数量达到一定数量时,对mysql的性能会
2022-06-04

怎么用Python实现简易的自制头像神器

这篇文章主要介绍“怎么用Python实现简易的自制头像神器”,在日常操作中,相信很多人在怎么用Python实现简易的自制头像神器问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”怎么用Python实现简易的自制头
2023-06-29

如何用C++自己实现mysql数据库的连接池?

为什么是mysql?现在几乎所有的后台应用都要用到数据库,什么关系型的、非关系型的;正当关系的,不正当关系的;主流的和非主流的, 大到Oracle,小到sqlite,以及包括现在逐渐流行的基于物联网的时序数据库,比如涛思的TDengine,咱们中国人自己的开
如何用C++自己实现mysql数据库的连接池?
2015-05-02

简单介绍Python实现邮件自动下载的示例

本篇文章给大家带来了关于Python的相关知识,详细介绍了如何利用Python语言实现邮件自动下载以及附件解析功能,文中的示例代码讲解详细,感下面一起来看一下,希望对大家有帮助。【相关推荐:Python3视频教程 】开始码代码之前,我们先来了解一下三种邮件服务协议:1、SMTP协议SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议。相当于中转站,将邮件发送到客
2022-08-17

Android Studio连接MySql实现登录注册的示例代码

小编给大家分享一下Android Studio连接MySql实现登录注册的示例代码,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!具体如下:一、创建工程1、创建一个
2023-06-15

编程热搜

目录