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

自定义MySQL适配器类析构时报弱引用对象不存在错误如何解决

MySQL适配器析构方法弱引用报错排查与修复方案

报错核心原因

你遇到的ReferenceError: weakly-referenced object no longer exists报错本质是Python析构函数__del__的执行特性导致的:Python解释器退出时,对象属性的销毁顺序没有明确保证,mysql.connector的游标对象内部持有连接对象的弱引用,当__del__执行时,连接对象可能已经被GC优先回收,导致游标对应的弱引用失效。
另外你的初始化代码存在笔误:__init__接收了database参数,但没有赋值给实例属性self.database,直接在connect方法中调用self.database会触发属性未定义问题,需要先修正。

排查步骤

  • 打印析构执行时的实例属性状态:在__del__方法开头通过hasattr(self, 'cursor')、hasattr(self, 'connection')判断属性是否已经被回收,确认是否是销毁顺序导致的问题。
  • 验证实例生命周期:如果适配器实例存放在Flask的请求/应用上下文中,添加日志确认实例销毁时间点和Flask shutdown流程的先后顺序,排查上下文提前清理属性的可能性。
  • 排除驱动版本问题:确认你使用的mysql-connector-python版本没有已知的弱引用相关bug,可升级到最新稳定版本复现验证。

修复方案

方案1:优先使用上下文管理器替代__del__(最推荐)

主动管理资源生命周期,避免依赖GC自动回收,给适配器类实现上下文协议,使用时通过with语句调用,保证资源按正确顺序释放:

class MySQLAdapter:
    def __init__(self, database):
        # 修正笔误,先给实例属性赋值
        self.database = database
        self.connection = mysql.connector.connect(
            host = "xxx",
            database = self.database,
            port = "xxx",
            user = "xxx",
            password = "xxx",
        )
        self.cursor = self.connection.cursor()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # 按游标先、连接后的顺序释放,先判断属性有效性
        if hasattr(self, 'cursor') and self.cursor is not None:
            self.cursor.close()
        if hasattr(self, 'connection') and self.connection.is_connected():
            self.connection.close()

# 使用示例
with MySQLAdapter(database="test") as db:
    db.cursor.execute("SELECT * FROM xxx")

方案2:Flask场景下注册全局销毁回调

如果你的适配器是Flask应用内的全局/上下文绑定实例,通过Flask的teardown_appcontext钩子主动释放资源,完全不需要依赖__del__:

from flask import Flask, g

app = Flask(__name__)

def get_db_adapter():
    if 'db' not in g:
        g.db = MySQLAdapter(database="your_db")
    return g.db

# 应用上下文销毁时自动执行
@app.teardown_appcontext
def close_db_resources(error):
    db = g.pop('db', None)
    if db is not None:
        if hasattr(db, 'cursor'):
            db.cursor.close()
        if hasattr(db, 'connection') and db.connection.is_connected():
            db.connection.close()

方案3:保留__del__做兜底清理(仅作为补充方案)

如果必须保留__del__逻辑,添加有效性判断和异常捕获,避免操作已回收的对象:

def __del__(self):
    try:
        if hasattr(self, 'cursor'):
            self.cursor.close()
    except ReferenceError:
        pass
    try:
        if hasattr(self, 'connection') and self.connection.is_connected():
            self.connection.close()
    except ReferenceError:
        pass

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 07:27:04