Python中如何使用PooledDB数据库连接池并正确关闭连接?
close()关不掉
Python中如何使用PooledDB数据库连接池并正确关闭连接?
5 回复
close 只是关掉一个 connection 吧,连接池还在。建议用 sqlalchemy 的 pool,测试过,比 poolDB 性能更好并发更高
import pymysql
from dbutils.pooled_db import PooledDB
import threading
class DatabasePool:
def __init__(self):
# 创建连接池
self.pool = PooledDB(
creator=pymysql, # 使用pymysql作为底层连接库
maxconnections=10, # 连接池允许的最大连接数
mincached=2, # 初始化时创建的连接数
maxcached=5, # 连接池中空闲连接的最大数量
blocking=True, # 连接数达到最大时是否阻塞等待
host='localhost',
user='your_username',
password='your_password',
database='your_database',
charset='utf8mb4',
autocommit=True # 自动提交事务
)
def get_connection(self):
"""从连接池获取连接"""
return self.pool.connection()
def close_all(self):
"""关闭连接池中的所有连接"""
self.pool.close()
# 使用示例
def query_example():
db_pool = DatabasePool()
try:
# 从连接池获取连接
conn = db_pool.get_connection()
cursor = conn.cursor()
# 执行查询
cursor.execute("SELECT * FROM users WHERE id = %s", (1,))
result = cursor.fetchone()
print(f"查询结果: {result}")
# 关闭游标(重要!)
cursor.close()
# 连接会自动返回到连接池,无需手动关闭conn
# 因为PooledDB的connection()返回的是代理连接
except Exception as e:
print(f"查询出错: {e}")
finally:
# 在程序结束时关闭整个连接池
db_pool.close_all()
# 多线程环境下使用
def worker(thread_id, db_pool):
conn = db_pool.get_connection()
cursor = conn.cursor()
cursor.execute("SELECT NOW()")
print(f"线程{thread_id}: {cursor.fetchone()}")
cursor.close()
# 连接会自动返回到连接池
def multi_thread_example():
db_pool = DatabasePool()
threads = []
for i in range(5):
t = threading.Thread(target=worker, args=(i, db_pool))
threads.append(t)
t.start()
for t in threads:
t.join()
db_pool.close_all()
if __name__ == "__main__":
# 单线程示例
query_example()
# 多线程示例
multi_thread_example()
关键点:
- 正确关闭:只需要在程序退出时调用
close_all()关闭整个连接池,日常使用中连接会自动回收 - 连接获取:使用
pool.connection()获取连接,这是PooledDB的代理连接 - 游标管理:必须显式关闭游标(
cursor.close()),连接会自动返回到池中 - 多线程安全:PooledDB本身是线程安全的,多个线程可以共享同一个连接池实例
记住:不要手动关闭从连接池获取的连接对象,让连接池自己管理生命周期。
总结建议:让连接池管理连接生命周期,你只需要管好游标和最终关闭连接池。
sqlalchemy 的 pool 怎么用的?可以发个 demo 吗
#2 你自己去找个文档看看吧 sqlalchemy 的 pool 基本上什么都不做就行了,只需要很简单的配置
Pool 还需要管吗?

