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()

关键点:

  1. 正确关闭:只需要在程序退出时调用close_all()关闭整个连接池,日常使用中连接会自动回收
  2. 连接获取:使用pool.connection()获取连接,这是PooledDB的代理连接
  3. 游标管理:必须显式关闭游标(cursor.close()),连接会自动返回到池中
  4. 多线程安全:PooledDB本身是线程安全的,多个线程可以共享同一个连接池实例

记住:不要手动关闭从连接池获取的连接对象,让连接池自己管理生命周期。

总结建议:让连接池管理连接生命周期,你只需要管好游标和最终关闭连接池。

sqlalchemy 的 pool 怎么用的?可以发个 demo 吗

#2 你自己去找个文档看看吧 sqlalchemy 的 pool 基本上什么都不做就行了,只需要很简单的配置

Pool 还需要管吗?

回到顶部