You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python大数据处理中MySQL连接池缺失及PyMySQL运行报错求助

解决PyMySQL长时间运行后出现的「无法分配请求地址」连接错误

嘿,这个问题我之前帮不少人排查过,本质上是连接没管好导致的端口耗尽,咱们一步步来解决:

首先得搞懂报错的原因:你每次处理数据时如果都新建一个MySQL连接,用完又没正确关闭(或者关闭后TCP连接进入TIME_WAIT状态没及时释放),系统的本地端口很快就会被耗尽,这就出现了pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 99] Cannot assign requested address)")这个错误。

Python确实没有像Java HikariCP那样官方标准的连接池,但有几个非常成熟的替代方案,完全能解决你的问题:

方案一:用SQLAlchemy(最推荐)

SQLAlchemy是Python生态里最常用的ORM框架,它内置的连接池非常稳定,自动帮你处理连接的复用、回收、重连,不用你手动操心。示例代码如下:

from sqlalchemy import create_engine

# 创建带连接池的引擎,可根据你的并发量调整pool_size和max_overflow
engine = create_engine(
    'mysql+pymysql://your_user:your_password@127.0.0.1/your_db?charset=utf8mb4',
    pool_size=20,  # 连接池保持的最小连接数
    max_overflow=10  # 超出pool_size的临时连接数,用完会回收
)

# 处理数据时直接用上下文管理器获取连接
with engine.connect() as conn:
    # 执行SQL
    result = conn.execute("INSERT INTO status_table (status, data_id) VALUES (%s, %s)", ("processed", 123))
    conn.commit()

用这种方式,你再也不用手动管理连接的创建和关闭,SQLAlchemy会帮你把连接池维护得妥妥的。

方案二:用DBUtils(专注连接池的库)

如果你不想用ORM,只想单纯用连接池,DBUtils是个不错的选择,它专门为Python的DB API 2.0实现了连接池,有两种模式可选:

from dbutils.pooled_db import PooledDB
import pymysql

# 初始化连接池
pool = PooledDB(
    creator=pymysql,  # 指定用PyMySQL作为连接创建器
    maxconnections=20,  # 连接池最大连接数
    mincached=5,  # 初始化时在连接池创建的空闲连接数
    maxcached=10,  # 连接池最多空闲的连接数
    host='127.0.0.1',
    user='your_user',
    password='your_password',
    database='your_db',
    charset='utf8mb4'
)

# 获取连接(注意:这里的close不是真的关闭,而是放回连接池)
conn = pool.connection()
try:
    cursor = conn.cursor()
    cursor.execute("UPDATE status_table SET status = 'done' WHERE id = %s", (456,))
    conn.commit()
finally:
    cursor.close()
    conn.close()

临时应急方案(不推荐长期用)

如果暂时不想引入新库,那你必须确保复用连接,而不是每次处理数据都新建,并且用完后正确关闭资源:

import pymysql

# 程序启动时只创建一次连接
conn = pymysql.connect(
    host='127.0.0.1',
    user='your_user',
    password='your_password',
    database='your_db',
    charset='utf8mb4'
)

def process_single_data(data):
    cursor = None
    try:
        cursor = conn.cursor()
        cursor.execute("INSERT INTO status_table ...", data)
        conn.commit()
    except pymysql.err.OperationalError as e:
        # 如果连接断开,重新建立连接
        global conn
        conn = pymysql.connect(host='127.0.0.1', user='your_user', password='your_password', database='your_db')
        # 重新执行操作
        cursor = conn.cursor()
        cursor.execute("INSERT INTO status_table ...", data)
        conn.commit()
    except Exception as e:
        conn.rollback()
        # 处理其他异常
    finally:
        if cursor:
            cursor.close()

# 批量处理数据
for data in your_large_data_set:
    process_single_data(data)

# 程序结束时关闭连接
conn.close()

不过这个方案有局限性,比如多线程场景下单连接会有线程安全问题,而且重连逻辑需要自己维护,不如用成熟的连接池库省心。

总结一下:Python虽然没有像HikariCP那样的「标准」连接池,但SQLAlchemy和DBUtils都是工业级的解决方案,完全能满足你处理大量数据时的连接管理需求,赶紧换掉原来的裸连方式吧!

内容的提问来源于stack exchange,提问作者Geek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:03:13