查找 PyMySQL 错误的来源 - err.InterfaceError("(0, '')")

Posted

技术标签:

【中文标题】查找 PyMySQL 错误的来源 - err.InterfaceError("(0, \'\')")【英文标题】:Finding source of PyMySQL error - err.InterfaceError("(0, '')")查找 PyMySQL 错误的来源 - err.InterfaceError("(0, '')") 【发布时间】:2019-10-12 15:49:02 【问题描述】:

我是 Discord 机器人开发人员,最近完成了一个订单。客户端在他们的服务器上设置应用程序最初没有问题,但据他们说,在运行“大约三个小时”后,程序开始吐出特定的堆栈跟踪错误并且不再接受命令。

机器人是使用 Discord.py 构建的,并使用 Peewee 作为 ORM,使用 Pymysql 作为数据库驱动程序。客户端运行它的服务器由 DigitalOcean 托管,如果需要有关硬件等的任何信息,客户端可以根据请求向我提供该信息。我们已经尝试卸载并重新安装所有依赖项,并尝试了它们的不同发行版,但错误仍然存​​在。

这是客户端正在接收的确切跟踪:

  File "/usr/local/lib/python3.6/dist-packages/peewee.py", line 2666, in __exit__
    reraise(new_type, new_type(*exc_args), traceback)
  File "/usr/local/lib/python3.6/dist-packages/peewee.py", line 179, in reraise
    raise value.with_traceback(tb)
  File "/usr/local/lib/python3.6/dist-packages/peewee.py", line 2875, in execute_sql
    cursor.execute(sql, params or ())
  File "/usr/local/lib/python3.6/dist-packages/pymysql/cursors.py", line 170, in execute
    result = self._query(query)
  File "/usr/local/lib/python3.6/dist-packages/pymysql/cursors.py", line 328, in _query
    conn.query(q)
  File "/usr/local/lib/python3.6/dist-packages/pymysql/connections.py", line 516, in query
    self._execute_command(COMMAND.COM_QUERY, sql)
  File "/usr/local/lib/python3.6/dist-packages/pymysql/connections.py", line 750, in _execute_command
    raise err.InterfaceError("(0, '')")
peewee.InterfaceError: (0, '')

我的 database.py 文件中的相关部分,其中打开了数据库连接:

import discord
from peewee import *

from config import db_host, db_port, mysql_db_name, \
    mysql_db_username, mysql_db_password

db_connection = MySQLDatabase(
    mysql_db_name,
    user = mysql_db_username,
    password = mysql_db_password,
    host = db_host,
    port = db_port
)

def create_db_tables():
    # create_tables() does safe creation by default, and will simply not create
    # table if it already exists
    db_connection.create_tables([User])

我的 bot.py 文件中的相关部分,特别是第一次打开 bot 时运行的 bot 启动函数,以及创建和启动 bot 客户端的行:

client = discord.Client()

async def bot_startup():
    # Check for config changes
    if client.user.name != config.bot_username:
        print("Username Updated To: ".format(config.bot_username))
        await client.edit_profile(username=config.bot_username)

    # Start 'playing' message
    await client.change_presence(
        game=discord.Game( name=config.playing_message )
    )

    # Prepare database
    database.create_db_tables()
    print("Database Connected")

    print("Connected Successfully")

# ...

@client.event
async def on_ready():
    await bot_startup()

# ...

client.run(config.token)

根据客户的说法,重新启动机器人可以暂时解决问题,并且在错误再次启动之前可以正常运行几个小时。一旦错误开始,机器人将不再响应任何传入的命令,如果抛出足够多的错误,则会完全崩溃。

此错误的典型原因是什么,应采取哪些步骤来解决导致该错误的原因?

【问题讨论】:

这能回答你的问题吗? InterfaceError (0, '') 【参考方案1】:

discord.py 是 asynchronousPyMySQL 不是 - 因此它阻塞了 discord.py 运行时。而不是PyMySQL 使用AIOMySQL,它是非阻塞的,可能只是解决您的错误。

【讨论】:

【参考方案2】:

错误出现的时机让我想起了我在与数据库通信时也遇到的问题。

问题可能是由于连接在机器人启动时打开(甚至在程序开始执行时)并且偶尔使用,数据库可能会关闭连接,因此任何进一步的执行都会导致错误。为了解决这个问题,我为我的数据库类的所有方法创建了这个装饰器

def ensures_connected(f):
    def wrapper(*args):
        args[0].connection.ping(reconnect=True, attempts=3, delay=2)
        return f(*args)

    return wrapper

放置在必须与数据库通信的任何方法或函数之上。

args[0].connection.ping(reconnect=True, attempts=3, delay=2) 行意味着我们将调用self.connection(因为它是调用时传递给方法的第一个参数)方法ping,如果连接断开,则允许reconnect。

我的代码中的self.connection 是方法调用MySQLConnection.connect 返回的对象,应该等同于您的对象db_connection

这个装饰器应该像下面的例子一样放在方法定义的上方:


def ensures_connected(f):
    def wrapper(*args):
        args[0].connection.ping(reconnect=True, attempts=3, delay=2)
        return f(*args)

    return wrapper

class Database:
    def __init__(self):
        self.connection = mysql.connector.connect(
            user=self.username, password=password, host=self.host, database=self.database)

    # ...

    @ensures_connected
    def is_member_registered(self, guild: Guild, member: Member):
        # ...
        return

【讨论】:

以上是关于查找 PyMySQL 错误的来源 - err.InterfaceError("(0, '')")的主要内容,如果未能解决你的问题,请参考以下文章

无法与 PyMySQL 建立远程连接(pymysql.err.InternalError:数据包序列号错误)

PyMySQL 内部错误:数据包顺序错误

node-sass build err in windows !

pymysql 错误信息(INSERT INTO 函数)

PyMySQL 代码 Windows 10 Python 3.5.0 中的连接错误?

初学者:使用 Anaconda 安装 PyMySQL(语法错误)