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

持续运行的Python脚本中数据库连接的优化策略咨询

优化持续运行Python脚本的数据库连接与异常处理方案

嘿,你的问题我太懂了——长连接容易丢,每次重连又嫌麻烦,还得天天重启脚本,确实闹心。下面给你几个实用的解决方案,一步步帮你搞定:

方案1:使用数据库连接池(最推荐)

连接池会帮你管理一组数据库连接,自动处理连接的创建、复用和失效回收,完美平衡“避免频繁重连”和“防止连接失效”的矛盾。用mysql.connector自带的连接池就能实现:

import mysql.connector
from mysql.connector import pooling
import schedule
import time

# 初始化连接池
dbconfig = {
    "user": DB_USER,
    "password": DB_PASSWORD,
    "host": "XYZ",
    "database": DB_NAME,
}
cnxpool = mysql.connector.pooling.MySQLConnectionPool(
    pool_name="mypool",
    pool_size=5,  # 单线程任务设置1个也足够,按需调整
    **dbconfig
)

def job():
    cnx = None
    cursor = None
    try:
        # 从连接池获取连接
        cnx = cnxpool.get_connection()
        cursor = cnx.cursor()
        
        # 执行你的解析和数据库操作
        run_parser1(cnx, cursor)
        run_parser2(cnx, cursor)
        
        cnx.commit()  # 别忘了提交事务
    except mysql.connector.Error as db_err:
        print(f"数据库错误: {db_err}")
        if cnx:
            cnx.rollback()  # 出错回滚事务
    except Exception as e:
        print(f"其他错误: {e}")
    finally:
        # 关闭游标和连接(连接会放回连接池,并非真正关闭)
        if cursor:
            cursor.close()
        if cnx:
            cnx.close()

schedule.every(30).seconds.do(job)
while True:
    schedule.run_pending()
    time.sleep(1)

连接池会自动处理连接有效性,如果某个连接失效,下次get_connection()会自动创建新连接,完全不用你手动操心。

方案2:任务前检查连接有效性,失效则重连

如果不想用连接池,也可以在每次任务执行前先验证当前连接是否可用,失效就重新建立:

import mysql.connector
import schedule
import time

cnx = None
cursor = None

def get_valid_connection():
    global cnx, cursor
    try:
        # 检查连接是否存活
        if cnx and cnx.is_connected():
            return cnx, cursor
        # 连接失效或未初始化,重新建立
        cnx = mysql.connector.connect(user=DB_USER, password=DB_PASSWORD, host='XYZ', database=DB_NAME)
        cursor = cnx.cursor()
        return cnx, cursor
    except Exception as e:
        print(f"重新连接数据库失败: {e}")
        # 清理无效连接
        if cnx:
            try:
                cnx.close()
            except:
                pass
        if cursor:
            try:
                cursor.close()
            except:
                pass
        cnx = None
        cursor = None
        raise  # 抛出异常让上层处理

def job():
    try:
        cnx, cursor = get_valid_connection()
        # 执行解析和数据库操作
        run_parser1(cnx, cursor)
        run_parser2(cnx, cursor)
        cnx.commit()
    except Exception as e:
        print(f"任务执行失败: {e}")
        # 网络类错误可以跳过本次任务,不影响后续执行

schedule.every(30).seconds.do(job)
while True:
    schedule.run_pending()
    time.sleep(1)

这个方案既保持了连接复用,又能确保每次任务用的都是活连接,避免了连接丢失导致的报错。

方案3:异常捕获后自动重建连接,不中断脚本

针对你之前代码的问题——一旦job里出现异常关闭了连接,后续任务就会因为cnx/cursor已关闭而失败。可以修改异常处理逻辑,在捕获到连接相关异常时自动重建连接:

import mysql.connector
import schedule
import time

cnx = None
cursor = None

def init_connection():
    global cnx, cursor
    try:
        cnx = mysql.connector.connect(user=DB_USER, password=DB_PASSWORD, host='XYZ', database=DB_NAME)
        cursor = cnx.cursor()
        print("数据库连接建立成功")
    except Exception as e:
        print(f"初始化连接失败: {e}")
        raise

# 初始化初始连接
init_connection()

def job():
    global cnx, cursor
    try:
        # 自动检查并重建连接
        cnx.ping(reconnect=True)
        # 执行解析和数据库操作
        run_parser1(cnx, cursor)
        run_parser2(cnx, cursor)
        cnx.commit()
    except mysql.connector.Error as db_err:
        print(f"数据库错误,尝试重建连接: {db_err}")
        # 清理旧连接
        try:
            cursor.close()
            cnx.close()
        except:
            pass
        # 重新初始化连接
        init_connection()
    except Exception as e:
        print(f"解析或其他错误: {e}")
        cnx.rollback()  # 出错回滚事务

schedule.every(30).seconds.do(job)
while True:
    schedule.run_pending()
    time.sleep(1)

这里用了cnx.ping(reconnect=True),它会自动检查连接状态,如果断开就尝试重连;就算重连失败,也会捕获异常并重新初始化连接,不会让脚本直接挂掉。

额外小贴士

  • 事务处理:数据库操作后一定要commit(),出错时记得rollback(),避免数据不一致。
  • 日志记录:用logging模块把错误信息详细记录到文件,方便后续排查问题。
  • 站点异常隔离:在run_parser里单独捕获网络异常(比如requests.exceptions.RequestException),别让站点不可用的问题连累数据库连接。
  • 优雅退出:给脚本加信号处理(比如SIGINT),收到退出信号时先关闭数据库连接再退出,避免连接泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 19:22:37