在调试自动化代码时,pymysql一直报:pymysql.err.InterfaceError: (0, ‘‘)

Traceback (most recent call last):
  File "F:/gitee/first/xzProjectTeamApi/lmsfirst_com/apiTemplate/parameter.py", line 71, in <module>
    bb = aa.parameterization(cc)
  File "F:/gitee/first/xzProjectTeamApi/lmsfirst_com/apiTemplate/parameter.py", line 62, in parameterization
    data = self.common_data(tp.department, data, self.com.department())
  File "F:\gitee\first\xzProjectTeamApi\lmsfirst_com\apiDatabase\common_info.py", line 31, in department
    get_data = self.get_mysql_data(sql, self.company_id, is_more=True)
  File "F:\gitee\first\xzProjectTeamApi\lmsfirst_com\common\handle_mysql.py", line 28, in get_mysql_data
    cur.execute(sql, args=args)
  File "D:\Python\Python37\lib\site-packages\pymysql\cursors.py", line 170, in execute
    result = self._query(query)
  File "D:\Python\Python37\lib\site-packages\pymysql\cursors.py", line 328, in _query
    conn.query(q)
  File "D:\Python\Python37\lib\site-packages\pymysql\connections.py", line 516, in query
    self._execute_command(COMMAND.COM_QUERY, sql)
  File "D:\Python\Python37\lib\site-packages\pymysql\connections.py", line 750, in _execute_command
    raise err.InterfaceError("(0, '')")
pymysql.err.InterfaceError: (0, '')

查阅资料后,得到的结论是:数据库连接时间太长了,断开了导致的错误...

 

图片

 

接下来。装逼开始....

 

具体与原因:

mysql数据库有一个wait_timeout的配置,默认值为28800(即8小时).

如果服务启动8小时侯,再次访问mysql数据库的时候,mysql数据库会拒绝访问。

 

查看超时时间:show variables like  '%timeout%';



 

解决方法如下:

 

第一种:增加ping方法:

 

增加一个段代码即可:

self.conn.ping(reconnect=True)

在游标创建前去看看有没有断开连接,断开就再连接上,保证后面execute时不报错

# 部分代码展示

    def get_mysql_data(self, sql, args=None, is_more=False):
        """
        获取数据库数据
        :param sql:         sql语句
        :param args:        元组参数
        :param is_more:     判断为真为假
        :return:            为真拿多条数据,为假拿一条数据
        """
        self.conn.ping(reconnect=True)
        cur = self.conn.cursor()
        cur.execute(sql, args=args)
        self.conn.commit()
        if is_more:
            return cur.fetchall()
        else:
            return cur.fetchone()

这种虽然简单但是会比较耗费性能...

 

第二种:引用线程池

from dbutils.pooled_db import PooledDB

# 部分代码展示


import pymysql
from dbutils.pooled_db import PooledDB
from first_com.common.switch_environment import base_db


class HandelMySql:

    def __init__(self):
        connkwargs = PooledDB(
            creator=pymysql,
            blocking=True,
            ping=1,  # 检查连接。默认1,即当连接被取走,做一次ping操作。0是从不ping,1是默认,2是当该连接创建游标时ping,4是执行sql语句时ping,7是总是ping
            **base_db(),
            charset='utf8',
            cursorclass=pymysql.cursors.DictCursor
        )

        self.conn = connkwargs.connection()

    def get_mysql_data(self, sql, args=None, is_more=False):
        """
        获取数据库数据
        :param sql:         sql语句
        :param args:        元组参数
        :param is_more:     判断为真为假
        :return:            为真拿多条数据,为假拿一条数据
        """
        cur = self.conn.cursor()
        cur.execute(sql, args=args)
        self.conn.commit()
        if is_more:
            return cur.fetchall()
        else:
            return cur.fetchone()
 __init__(self)方法中就是设置了线程池的操作...

比较权威栗子查看连接

 

下面图片是官网对池化数据库的一些描述及运行效果图,可供查考

 


 

至此,问题解决完毕,继续撸代码了...

图片

 

以上总结或许能帮助到你,或许帮助不到你,但还是希望能帮助到你,如有疑问、歧义,评论区留言会及时修正发布,谢谢!

未完,待续…

一直都在努力,希望您也是

微信搜索公众号:就用python

 

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐