python3 mysql|MariaDB 重连异常 pymysql.OperationalError

背景信息:

使用之前python2的mysql库,在python3下运行,由于MariaDB重启,或者句柄失效重连MariaDB时出现bug:

在机器重启启动MariaDB后,发现API接口报错,报错日志如下:

sql error:'OperationalError' object does not support indexing,

pymysql.err.OperationalError: (2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))")

在python3 代码中增加日志打印:

logging.error('type: %s, str: %s, type: %s, args0:%s, args1:%s', type(errno), str(errno), type(errno.args), errno.args[0], errno.args[1])

打印结果:

type: <class 'pymysql.err.OperationalError'>, str: (2013, 'Lost connection to MySQL server during query'), type: <class 'tuple'>, args0:2013, args1:Lost connection to MySQL server during query

以下代码非完整代码,区别点:

在python2中pymysql.OperationalError 与python3中的使用方法不同

python2中使用pymysql.OperationalError[0]

python3中使用pymysql.err.OperationalError.args[0],多了一个args

Python 3.6.8 (default, Aug  7 2019, 17:28:10) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import pymysql  
>>> dir(pymysql.OperationalError)
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', '__weakref__', 'args', 'with_traceback']

在python2中使用 pymysql.err.OperationalError[0]没问题:

def execute(sql, param=None):
    try:
        g_db_cur.execute(sql, param)
    except pymysql.OperationalError as errno:
        err_msg = 'mysql_query failed (%d: %s) [%s]\n' % (errno[0], errno[1], sql)
        logging.error(err_msg)
        if errno[0] == 2006 or errno[0] == 2013 or errno[0] == 2002: #CR_SERVER_GONE_ERROR, CR_SERVER_LOST, CR_CONNECTION_ERROR
           #重连
        else:
            raise(pymysql.OperationalError, [errno[0], errinfo])
    except pymysql.ProgrammingError as e:
        pass

在python3中使用 pymysql.err.OperationalError.args[0]

def execute(sql, param=None):
    try:
        g_db_cur.execute(sql, param)
    except pymysql.err.OperationalError as errno:
        if errno.args[0] == 2006 or errno.args[0] == 2013 or errno.args[0] == 2002: #CR_SERVER_GONE_ERROR, CR_SERVER_LOST, CR_CONNECTION_ERROR
           #重连
        elif errno.args[0] == 1213: #ER_LOCK_DEADLOCK
           pass
        else:
            pass
    except pymysql.ProgrammingError as e:
        pass

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值