pymysql.err.InterfaceError:对sql表执行大量推送时出现(0,“”)错误

8fq7wneg  于 2023-02-11  发布在  Mysql
关注(0)|答案(5)|浏览(219)

我正在短时间内从使用了很多不同线程的Python代码(使用Pymysql)向一个mysql表做很多插入。
每个线程(有许多线程)最终可能会也可能不会将数据推送到MySql表。
以下是导致此问题的代码块(可以为每个运行的线程调用此代码块):

sql = ("INSERT INTO LOCATIONS (location_id, place_name) VALUES (%s, %s)")
        cursor = self.connection.cursor()          
        cursor.execute(sql, (location_id, place_name))     
        cursor.close()

具体来说就是这句话

cursor.execute(sql, (location_id, place_name))

这会导致以下错误:

pymysql.err.InterfaceError: (0, '')

还要注意的是,我在上述代码块所在的类的init中定义了self. connection。因此,所有线程共享self. connection对象,但获得自己的游标对象。
这个错误似乎是随机发生的,只有在对mysql表做了相当多的插入操作后才开始出现(我认为)。这是不一致的,意味着它不会在每次尝试插入mysql时发生。
我已经在谷歌上搜索了这个特定的错误,它似乎可能是从游标被关闭之前运行查询。但我相信这是显而易见的,我关闭游标后,查询执行。
现在我认为这是因为:
1.对MySql表的某种写入限制,尽管pymysql.err.InterfaceError的错误似乎没有明确说明这一点
1.事实上,我有一个定义在高作用域的连接,它有从线程中创建的游标,这可能会导致这个问题。
有什么想法?

iqjalb3h

iqjalb3h1#

看起来这个问题与我有一个通用连接对象有关。每个线程创建一个似乎已经消除了这个问题。

zbwhf8kr

zbwhf8kr2#

我也遇到了同样的问题。我的项目代码中有一个全局连接,我发现如果长时间没有mysql操作,这个连接会超时。这个错误会在执行sql任务时发生,因为连接超时。
我的解决方案是:在执行sql任务之前重新连接mysql。

sql = ("INSERT INTO LOCATIONS (location_id, place_name) VALUES (%s, %s)")
    self.connnection.ping()  # reconnecting mysql
    with self.connection.cursor() as cursor:         
        cursor.execute(sql, (location_id, place_name))
chhkpiq4

chhkpiq43#

我也遇到了同样的错误,我发现pymysql是线程安全的,所以你需要像@ sometimesi写代码说的那样为每个线程打开一个连接。
找到的来源:https://github.com/PyMySQL/PyMySQL/issues/422

dnph8jn4

dnph8jn44#

不要关闭连接删除游标.close()行应该继续更新数据库

ma8fv8wu

ma8fv8wu5#

在升级到新的PyMySQL版本后,我突然遇到了同样的错误,但没有做很多查询。我还遇到了一个额外的错误:

[..]
pymysql.err.InterfaceError: (0, '')

During handling of the above exception, another exception occurred:

pymysql.err.Error: Already closed

由于这似乎是唯一真正讨论这个错误的地方,我也将在这里发布我的解决方案。
根据PyMySQL文档,我是这样做的:

connection = pymysql.connect([...])

with connection:
    with connection.cursor() as cursor:
        [..]
        cursor.execute(sql)

# lots of other code

with connection:
    [...]

我没有注意到的是,当上下文管理器执行完毕时,with connection会自动关闭到数据库的连接,因此后续查询会失败,即使我仍然能够从连接中获得游标而没有错误。
解决方案是不使用with connection上下文管理器,而是手动关闭数据库连接:

connection = pymysql.connect([...])

with connection.cursor() as cursor:
    [..]
    cursor.execute(sql)

# lots of other code

with connection.cursor() as cursor:
    [..]

connection.close()

相关问题