Python連接MySQL數(shù)據(jù)庫(kù)連接池的操作詳解
問(wèn)題
對(duì)于數(shù)據(jù)庫(kù)連接,一般不建議使用全局變量,在每次操作完成后即關(guān)閉連接。這是因?yàn)殚L(zhǎng)時(shí)間保持?jǐn)?shù)據(jù)庫(kù)連接會(huì)對(duì)性能和資源消耗產(chǎn)生負(fù)面影響。與此相反,使用數(shù)據(jù)庫(kù)連接池來(lái)維護(hù)和分配數(shù)據(jù)庫(kù)連接是更好的做法。
好處
連接池的優(yōu)點(diǎn)是可以在多個(gè)線程或進(jìn)程之間共享,并且可以有效地管理連接數(shù),而無(wú)需手動(dòng)打開(kāi)和關(guān)閉連接。
常用包
SQLAlchemy 中的 QueuePool 和 DBUtils 中的 PooledDB 都是流行的 Python數(shù)據(jù)庫(kù)連接池實(shí)現(xiàn),它們具有相似的功能但具有一些區(qū)別。
QueuePool 是 SQLAlchemy 內(nèi)置的一個(gè)連接池實(shí)現(xiàn),它可以管理一個(gè)連接隊(duì)列,確保每個(gè)連接在使用后被適當(dāng)?shù)仃P(guān)閉。該池使用Python 自帶的 queue 模塊實(shí)現(xiàn),并支持可配置的最大連接數(shù)、預(yù)處理語(yǔ)句等特性。優(yōu)點(diǎn)是易于使用,無(wú)需其他依賴,并與SQLAlchemy 之間無(wú)縫集成。
PooledDB 是 DBUtils 庫(kù)提供的一個(gè)連接池實(shí)現(xiàn),可以與 SQLAlchemy 或其他 Python數(shù)據(jù)庫(kù)庫(kù)一起使用。它支持多種類型的連接池,并使用 threading模塊實(shí)現(xiàn)線程安全,具有更高的性能和穩(wěn)定性。該庫(kù)還提供了一些方便的功能,例如自動(dòng)回收空閑連接等。
總結(jié)以上還是使用 DBUtils 比較好些
代碼
import pymysql
from DBUtils.PooledDB import PooledDB
host = 'localhost'
port = 3306
user = 'root'
password = '123456'
database = 'mytest'
class MySQLConnectionPool:
def __init__(self,):
self.pool = PooledDB(
creator=pymysql, # 使用鏈接數(shù)據(jù)庫(kù)的模塊
mincached=10, # 初始化時(shí),鏈接池中至少創(chuàng)建的鏈接,0表示不創(chuàng)建
maxconnections=200, # 連接池允許的最大連接數(shù),0和None表示不限制連接數(shù)
blocking=True, # 連接池中如果沒(méi)有可用連接后,是否阻塞等待。True,等待;False,不等待然后報(bào)錯(cuò)
host=host,
port=port,
user=user,
password=password,
database=database
)
def open(self):
self.conn = self.pool.connection()
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) # 表示讀取的數(shù)據(jù)為字典類型
return self.conn, self.cursor
def close(self, cursor, conn):
cursor.close()
conn.close()
def select_one(self, sql, *args):
"""查詢單條數(shù)據(jù)"""
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchone()
self.close(conn, cursor)
return result
def select_all(self, sql, args):
"""查詢多條數(shù)據(jù)"""
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchall()
self.close(conn, cursor)
return result
def insert_one(self, sql, args):
"""插入單條數(shù)據(jù)"""
self.execute(sql, args, isNeed=True)
def insert_all(self, sql, datas):
"""插入多條批量插入"""
conn, cursor = self.open()
try:
cursor.executemany(sql, datas)
conn.commit()
return {'result': True, 'id': int(cursor.lastrowid)}
except Exception as err:
conn.rollback()
return {'result': False, 'err': err}
def update_one(self, sql, args):
"""更新數(shù)據(jù)"""
self.execute(sql, args, isNeed=True)
def delete_one(self, sql, *args):
"""刪除數(shù)據(jù)"""
self.execute(sql, args, isNeed=True)
def execute(self, sql, args, isNeed=False):
"""
執(zhí)行
:param isNeed 是否需要回滾
"""
conn, cursor = self.open()
if isNeed:
try:
cursor.execute(sql, args)
conn.commit()
except:
conn.rollback()
else:
cursor.execute(sql, args)
conn.commit()
self.close(conn, cursor)
"""
CREATE TABLE `names` (
`id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主鍵',
`name` VARCHAR(30) DEFAULT NULL COMMENT '姓名',
`sex` VARCHAR(20) DEFAULT NULL COMMENT '性別',
`age` int(5) DEFAULT NULL COMMENT '年齡',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='數(shù)據(jù)導(dǎo)入mysql';
"""
mysql = MySQLConnectionPool()
sql_insert_one = "insert into `names` (`name`, sex, age) values (%s,%s,%s)"
mysql.insert_one(sql_insert_one, ('唐三', '男', 25))
datas = [
('戴沐白', '男', 26),
('奧斯卡', '男', 26),
('唐三', '男', 25),
('小舞', '女', 100000),
('馬紅俊', '男', 23),
('寧榮榮', '女', 22),
('朱竹清', '女', 21),
]
sql_insert_all = "insert into `names` (`name`, sex, age) values (%s,%s,%s)"
mysql.insert_all(sql_insert_all, datas)
sql_update_one = "update `names` set age=%s where `name`=%s"
mysql.update_one(sql_update_one, (28, '唐三'))
sql_delete_one = 'delete from `names` where `name`=%s '
mysql.delete_one(sql_delete_one, ('唐三',))
sql_select_one = 'select * from `names` where `name`=%s'
results = mysql.select_one(sql_select_one, ('唐三',))
print(results)
sql_select_all = 'select * from `names` where `name`=%s'
results = mysql.select_all(sql_select_all, ('唐三',))
print(results)
Python使用連接池操作MySQL
測(cè)試環(huán)境說(shuō)明:Python版本是 3.8.10 ,DBUtils版本是3.1.0 ,pymysql版本是1.0.3
首先安裝指定版本的連接池庫(kù)DBUtils 、還有pymysql
pip install DBUtils==3.1.0 pip install pymysql==1.0.3
創(chuàng)建文件 sqlConfig.py
# sqlConfig.py
import pymysql
from dbutils.pooled_db import PooledDB
# 有些版本使用下面語(yǔ)句引入,要注意一下
# from DBUtils.PooledDB import PooledDB
host = '127.0.0.1'
port = 3306
user = 'myname'
password = 'mypass'
database = 'contest'
class MySQLConnectionPool:
def __init__(self,):
self.pool = PooledDB(
creator=pymysql, # 使用鏈接數(shù)據(jù)庫(kù)的模塊
mincached=10, # 初始化時(shí),鏈接池中至少創(chuàng)建的鏈接,0表示不創(chuàng)建
maxconnections=200, # 連接池允許的最大連接數(shù),0和None表示不限制連接數(shù)
blocking=True, # 連接池中如果沒(méi)有可用連接后,是否阻塞等待。True,等待;False,不等待然后報(bào)錯(cuò)
host=host,
port=port,
user=user,
password=password,
database=database
)
def open(self):
self.conn = self.pool.connection()
self.cursor = self.conn.cursor(cursor=pymysql.cursors.DictCursor) # 表示讀取的數(shù)據(jù)為字典類型
return self.conn, self.cursor
def close(self, cursor, conn):
cursor.close()
conn.close()
def select_one(self, sql, *args):
"""查詢單條數(shù)據(jù)"""
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchone()
self.close(conn, cursor)
return result
def select_all(self, sql, args):
"""查詢多條數(shù)據(jù)"""
conn, cursor = self.open()
cursor.execute(sql, args)
result = cursor.fetchall()
self.close(conn, cursor)
return result
def insert_one(self, sql, args):
"""插入單條數(shù)據(jù)"""
self.execute(sql, args, isNeed=True)
def insert_all(self, sql, datas):
"""插入多條批量插入"""
conn, cursor = self.open()
try:
cursor.executemany(sql, datas)
conn.commit()
return {'result': True, 'id': int(cursor.lastrowid)}
except Exception as err:
conn.rollback()
return {'result': False, 'err': err}
def update_one(self, sql, args):
"""更新數(shù)據(jù)"""
self.execute(sql, args, isNeed=True)
def delete_one(self, sql, *args):
"""刪除數(shù)據(jù)"""
self.execute(sql, args, isNeed=True)
def execute(self, sql, args, isNeed=False):
"""
執(zhí)行
:param isNeed 是否需要回滾
"""
conn, cursor = self.open()
if isNeed:
try:
cursor.execute(sql, args)
conn.commit()
except:
conn.rollback()
else:
cursor.execute(sql, args)
conn.commit()
self.close(conn, cursor)
創(chuàng)建文件 sqlTest.py ,并引入sqlConfig.py使用
# sqlTest.py
# 引入連接池類
from sqlConfig import MySQLConnectionPool
# 創(chuàng)建連接池對(duì)象
ConnPool = MySQLConnectionPool()
# 模糊查詢
strSelectAll = "select * from names where name like %s"
results = ConnPool.select_all(strSelectAll, ('%唐%',))
print(results)
# 精確查詢
# strSelectAll = "select * from names where name=%s"
# results = ConnPool.select_all(strSelectAll, ('唐三',))
# print(results)
# 單條查詢
# strSelectOne = 'select * from `names` where `name`=%s'
# results = ConnPool.select_one(strSelectOne, ('唐三',))
# print(results)
# 單條插入
# strInsertOne = "insert into `names` (`name`, sex, age) values (%s,%s,%s)"
# ConnPool.insert_one(strInsertOne, ('唐三', '男', 22))
# 批量插入
# datas = [
# ('戴沐白', '男', 26),
# ('奧斯卡', '男', 26),
# ('唐三', '男', 25),
# ('小舞', '女', 100000),
# ('馬紅俊', '男', 23),
# ('寧榮榮', '女', 22),
# ('朱竹清', '女', 21),
# ]
# sql_insert_all = "insert into `names` (`name`, sex, age) values (%s,%s,%s)"
# ConnPool.insert_all(sql_insert_all, datas)
# sql_update_one = "update `names` set age=%s where `name`=%s"
# ConnPool.update_one(sql_update_one, (28, '唐三'))
# sql_delete_one = 'delete from `names` where `name`=%s '
# ConnPool.delete_one(sql_delete_one, ('唐三',))到此這篇關(guān)于Python連接MySQL數(shù)據(jù)庫(kù)連接池的操作詳解的文章就介紹到這了,更多相關(guān)Python MySQL數(shù)據(jù)庫(kù)連接池內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別
本文主要介紹了pandas重復(fù)行刪除操作df.drop_duplicates和df.duplicated的區(qū)別,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
一個(gè)基于flask的web應(yīng)用誕生 用戶注冊(cè)功能開(kāi)發(fā)(5)
一個(gè)基于flask的web應(yīng)用誕生第五篇,這篇文章主要介紹了用戶注冊(cè)功能開(kāi)發(fā),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04
pyqt 實(shí)現(xiàn)在Widgets中顯示圖片和文字的方法
今天小編就為大家分享一篇pyqt 實(shí)現(xiàn)在Widgets中顯示圖片和文字的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
PyCharm軟件無(wú)法安裝lxml庫(kù)的問(wèn)題及解決
這篇文章主要介紹了PyCharm軟件無(wú)法安裝lxml庫(kù)的問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
深入理解python中pytest.ini的配置方法和參數(shù)
Pytest 是 Python 測(cè)試框架中最流行的一個(gè),而 pytest.ini 文件則是 pytest 配置文件的核心,在本文中,將詳細(xì)介紹 pytest.ini 文件的配置方法和可能的參數(shù),幫助您更好地掌握 Pytest 的使用,需要的朋友可以參考下2024-10-10
利用python+ffmpeg合并B站視頻及格式轉(zhuǎn)換的實(shí)例代碼
這篇文章主要介紹了利用python+ffmpeg合并B站視頻及格式轉(zhuǎn)換的實(shí)例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
如何利用AJAX獲取Django后端數(shù)據(jù)詳解
ajax一個(gè)前后臺(tái)配合的技術(shù),它可以讓javascript發(fā)送http請(qǐng)求,與后臺(tái)通信,獲取數(shù)據(jù)和信息。下面這篇文章主要介紹了如何利用AJAX獲取Django后端數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2021-06-06

