python数据库连接池_Python实现数据库连接池

1.初始化

def __init__(self, **kwargs):

self.size = kwargs.get('size', 10)

self.kwargs = kwargs

self.conn_queue = queue.Queue(maxsize=self.size)

for i in range(self.size):

self.conn_queue.put(self._create_new_conn())

size:连接池支持的连接数,这里定义为10

conn_queue:定义了一个队列,队列存放的是数据库的连接

for循环:建立好十个与数据库的连接,把这些连接放到队列中

2.私有方法:连接数据库

def _create_new_conn(self):

return MySQLdb.connect(host=self.kwargs.get('host', '127.0.0.1'),

user=self.kwargs.get('user'),

passwd=self.kwargs.get('password'),

port=self.kwargs.get('port', 3306),

connect_timeout=5)

connect_timeout:在获取连接阶段起作用

获取MySQL连接是多次握手的结果,除了用户名和密码的匹配校验外,还有IP->HOST->DNS->IP验证,任何一步都可能因为网络问题导致线程阻塞。为了防止线程浪费在不必要的校验等待上,超过connect_timeout的连接请求将会被拒绝。

官方描述:connect_timeout(The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake. The default value is 10 seconds)

这里设置了5秒。

3.私有方法:put

def _put_conn(self, conn):

self.conn_queue.put(conn)

使用了queue的put方法,将连接放到队列中,put默认是阻塞调用,非阻塞版本为put_nowait()方法,相当于put(conn, False)

阻塞调用是指:调用返回结果之前,当前线程会被挂起,线程进入非可执行状态,在这个状态下CPU不会给线程分配时间片,线程暂停运行。函数只有在得到结果之后才会返回。

4.私有方法:获取连接

def _get_conn(self):

conn = self.conn_queue.get()

if conn is None:

self._create_new_conn()

return conn

当要连接数据库时,不再创建新的连接,而是之间从队列中获取连接,用完之后再把连接放回队列中,如果获取的连接为空,再新建连接。

get():如果队列为空,get会等待,直到队列里有数据以后再取值,get取值会在队列中移除一个数据,所以当取完连接用完之后,要再使用put方法把连接放回连接池。(get默认为阻塞调用,非阻塞调用方法为get_nowait())

get_nowait():取值的时候不等待,如果取不到值,程序直接崩溃,所以在获取队列的数据的时候要统一使用get,代码才不会有问题

使用get_nowait()和put_nowait()的时候要做捕获异常处理。

5.执行SQL语句函数

def exec_sql(self, sql):

conn = self._get_conn()

try:

with conn as cur:

cur.execute(sql)

return cur.fetchall()

except MySQLdb.ProgrammingError as e:

LOG.error("execute sql ({0}) error {1}".format(sql, e))

raise e

except MySQLdb.OperationalError as e:

conn = self._create_new_conn()

raise e

finally:

self._put_conn(conn)

传递进来的参数是SQL语句

获取连接后,一般要创建游标,然后使用游标再进行对数据的增删改查,这里使用了with语句,就不用再创建游标了。cur执行SQL语句,然后使用fetchall返回所有匹配的每个元素,每个元素作为一个元组组成一个大元组,最后返回的是这一个大元组。

然后捕获了两个异常,一个是语法错误异常,另一个是编码问题的异常。

最后无论是正常建立连接执行了SQL语句,还是发生了异常,都要把连接放回到连接队列中去。

6.删除连接

def __del__(self):

try:

while True:

conn = self.conn_queue.get_nowait()

if conn:

conn.close()

except queue.Empty:

pass

获取到连接之后用close关闭连接,如果取到的队列中的连接已经为空了,直接pass

其中queue.Empty的作用是,如果队列为空,返回True,如果不为空,返回False。

7.完整代码

# -*- coding:UTF-8 -*-

import queue

import MySQLdb

class ConnectionPool(object):

def __init__(self, **kwargs):

self.size = kwargs.get('size', 10)

self.kwargs = kwargs

self.conn_queue = queue.Queue(maxsize=self.size)

for i in range(self.size):

self.conn_queue.put(self._create_new_conn())

def _create_new_conn(self):

return MySQLdb.connect(host=self.kwargs.get('host', '127.0.0.1'),

user=self.kwargs.get('user'),

passwd=self.kwargs.get('password'),

port=self.kwargs.get('port', 3306),

connect_timeout=5)

def _put_conn(self, conn):

self.conn_queue.put(conn)

def _get_conn(self):

conn = self.conn_queue.get()

if conn is None:

self._create_new_conn()

return conn

def exec_sql(self, sql):

conn = self._get_conn()

try:

with conn as cur:

cur.execute(sql)

return cur.fetchall()

except MySQLdb.ProgrammingError as e:

# 可以加一行将异常记录到日志中

raise e

except MySQLdb.OperationalError as e:

conn = self._create_new_conn()

raise e

finally:

self._put_conn(conn)

def __del__(self):

try:

while True:

conn = self.conn_queue.get_nowait()

if conn:

conn.close()

except queue.Empty:

pass

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/470647.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Chapter6_Vocoder

文章目录1 Introduction2 WaveNet2.1 WaveNet的架构2.2 Softmax Distribution2.3 Causal Convolution和Dilated Convolution2.4 Gated Activation Unit2.5 小结3 FFTNet4 WaveRNN4.1 Dual Softmax Layer4.2 Model Coarse4.3 Model Fine4.4 小结5 WaveGlow本文为李弘毅老师【Voc…

show一下自己的文档编写功底

以我为例,我绝对相信,“才华”和颜值成反比。“才华”二字加了引号了,自知跟优秀有孙大圣一个筋斗云的距离,不过某些细节方面表现得被认为还不错,这里我要秀一下我的文档编写能力。在我这十年的工作生涯里,…

mysql命令速查手册

数据准备 -- 创建数据库 create database qianduan_test charsetutf8;-- 使用数据库 use qianduan_test;-- students表 create table students(id int unsigned primary key auto_increment not null,name varchar(20) default ,age tinyint unsigned default 0,height decima…

Chapter7-1_Overview of NLP Tasks

文章目录1 Introduction2 Part-of-Speech(POS) Tagging3 Word Segmentation4 Parsing5 Coreference Resolution6 Summarization7 Machine Translation8 Grammar Error Correction9 Sentiment classification10 Stance Detection11 Natural Language Inference(NLI)12 Search En…

python制作文本编辑器_Python小实战:制作文本编辑器

学了半年了,该施展一下了🍺 做什么呢?做一个简单的文本编辑器吧 来,开始 知识点: 1)做窗体的知识 2)文件操作 窗体用的是tkinter简单模块,系统自带模块 有人说了:“哇&am…

OGNL 详解

Struts2 OGNL详解 1.概念: OGNL是Object-Graph Navigation Language的缩写,全称为对象图导航语言,是一种功能强大的表达式语言,它通过简单一致的语法,可以任意存取对象的属性或者调用对象的方法,能够遍历整…

完善获取数据库数据的写法

上一篇:使用express搭建服务器获取MySQL数据库数据 一、完善获取数据库数据的写法 asyncawait版本: const express require(express) const db require(./db/nodejs-orm/index.js)const app express()app.get("/get_data", (req, res) …

Chapter7-2_BERT and its family - Introduction and Fine-tune

文章目录1 What is pre-train model2 How to fine-tune2.1 Input2.2 Output2.3 Fine-tune2.4 Weighted Features3 Why fine-tune本文为李弘毅老师【BERT and its family - Introduction and Fine-tune】的课程笔记,课程视频youtube地址,点这里&#x1f4…

python数据分析基础教程 numpy_Python数据分析基础教程:NumPy学习指南(第2版)

Python数据分析基础教程:NumPy学习指南(第2版) Ivan Idris (作者) 张驭宇 (译者) NumPy是一个优秀的科学计算库,提供了很多实用的数学函数、强大的多维数组对象和优异的计算性能,不仅可以取代Matlab和Mathematica的许多…

【BZOJ-2435】道路修建 (树形DP?)DFS

2435: [Noi2011]道路修建 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3115 Solved: 1002[Submit][Status][Discuss]Description 在 W 星球上有 n 个国家。为了各自国家的经济发展,他们决定在各个国家之间建设双向道路使得国家之间连通。但是每个国家的国王都…

CSRF跨站请求伪造

一、CSRF跨站请求伪造 CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造。 CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求。 包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品&a…

升级 ubuntu_Ubuntu 19.04 已经到期!现有用户必须升级到 Ubuntu 19.10

Ubuntu 19.04 已在 2020 年 1 月 23 日到期,这意味着运行 Ubuntu 19.04 的系统将不再会接收到安全和维护更新,因此将使其容易受到攻击。-- Abhishek Prakash(作者)Ubuntu 19.04 发布于 2019 年 4 月 18 日。由于它不是长期支持(LTS)版本,因此…

Chapter7-3_BERT and its family - ELMo, BERT, GPT, XLNet, MASS, BART, UniLM, ELECTRA, and more

文章目录1 How to pre-train2 Predict next token3 Mask Input4 seq2seq的pre-train model5 ELECTRA6 Sentence Embedding本文为李弘毅老师【BERT and its family - ELMo, BERT, GPT, XLNet, MASS, BART, UniLM, ELECTRA, and more】的课程笔记,课程视频youtube地址…

JavaScript调试工具

JavaScript代码看起来总是要比Java、C#乱的多,可能是自己还不熟悉JavaScript编程,因此一款优秀的JavaScript调试器就显得格外重要。目前在网络和书上见到最多的有: 第一个:Microsoft Script Debugger: 集成在IE中的一款很原始的调…

python中split函数_python strip()函数和Split函数的用法总结

strip函数原型 声明:s为字符串,rm为要删除的字符序列. 只能删除开头或是结尾的字符或是字符串。不能删除中间的字符或是字符串。 s.strip(rm) 删除s字符串中开头、结尾处,位于 rm删除序列的字符 s.lstrip(rm) 删除s字符串中开头处&#xff0c…

express项目搭建 初始化详细步骤

案例 一、对每一个POST请求都设置CSRF防护 实际上,不仅仅转账需要CSRF防护,每一个post请求都需要做csrf的防护措施。 webA项目中的app.js: const router express.Router();router.all("/register",(res,req)>{.... })funct…

Chapter7-4_來自獵人暗黑大陸的模型 GPT-3

文章目录1 为何来自暗黑大陆2 GPT-3的野心3 GPT-3的效果4 Beyond GPT-3本文为李弘毅老师【來自獵人暗黑大陸的模型 GPT-3】的课程笔记,课程视频youtube地址,点这里👈(需翻墙)。 下文中用到的图片均来自于李宏毅老师的PPT,若有侵权…

SetConsoleCtrlHandler() -- 设置控制台信号处理函数

http://www.groad.net/bbs/thread-8253-1-1.html 当你在命令行里工作时,经常会输入 Ctrl-C 这个组合键以停止程序的运行。SetConsoleCtrlHandler() 函数可以让一个或多个特定函数在接收到 Ctrl-C, Ctrl-break 这些与控制台有关的信号时得到执行。 BOOL WINAPI SetCo…

python提取txt中的字符串数据_python 从字符串中提取数值

python中用re.findall函数,里面写正则表达式 rootvdirectva:/home/lic_auto_scale# cat re.py import re test[10Mbps,100bps,6.7Gbps,0.8bps,10.562Kbps] for union in test : _sizere.findall(r\d\.*\d*,union) xusage re.findall(r\D*bps,union) print("si…

二、PHP框架Laravel学习笔记——路由的定义和控制器

一.路由的定义 什么是路由?路由就是提供接受 HTTP 请求的路径,并和程序交互的功能; 简单点理解,就是为了提供访问程序的 URL 地址,所做的一些设置工作; phpstorm 支持 cmd 操作,左…