SQLAlchemy错误MySQL服务器已消失

2024-04-27 20:03:05 发布

您现在位置:Python中文网/ 问答频道 /正文

错误OperationalError: (OperationalError) (2006, 'MySQL server has gone away')我在烧瓶上编码项目时已经收到此错误,但我无法理解为什么会出现此错误。

我有这样的代码(是的,如果代码很小并且执行速度很快,那么没有错误)

db_engine = create_engine('mysql://root@127.0.0.1/mind?charset=utf8', pool_size=10, pool_recycle=7200)
Base.metadata.create_all(db_engine)

Session = sessionmaker(bind=db_engine, autoflush=True)
Session = scoped_session(Session)
session = Session()

# there many classes and functions

session.close()

这段代码返回我的错误'MySQL server has gone away',但在一段时间后,当我在脚本中使用暂停时,返回它。

我从openserver.ru使用Mysql(它是类似wamp的web服务器)。

谢谢。。


Tags: 代码dbserver烧瓶session错误createmysql
3条回答

查看mysql文档,我们可以看到有一个bunch of reasons why this error can occur。不过,我看到的两个主要原因是:


1)最常见的原因是连接已断开,因为它已超过8小时未使用(默认设置)

By default, the server closes the connection after eight hours if nothing has happened. You can change the time limit by setting the wait_timeout variable when you start mysqld

为了完整起见,我只想提及两种处理方法,但在其他答案中已经提到过:

A:我有一个很长的运行任务,因此我的连接已过时。要解决此问题,我刷新连接:

create_engine(conn_str, pool_recycle=3600)  # recycle every hour

B:我有一个长时间运行的服务和长时间的不活动。要在每次调用之前修复此问题,请执行以下操作:

create_engine(conn_str, pool_pre_ping=True)

2)我的数据包太大,这会引发以下错误:

_mysql_exceptions.OperationalError: (1153, "Got a packet bigger than 'max_allowed_packet' bytes")

我只看到这个隐藏在跟踪的中间,尽管通常您只看到一般的_mysql_exceptions.OperationalError (2006, 'MySQL server has gone away'),所以很难捕获,特别是当日志位于多个位置时。

The above doc假设默认情况下最大数据包大小是64MB,但实际上是16MB,可以用SELECT @@max_allowed_packet验证

要解决此问题,请减小INSERTUPDATE调用的数据包大小。

documentation可以使用pool_recycle参数:

from sqlalchemy import create_engine
e = create_engine("mysql://scott:tiger@localhost/test", pool_recycle=3600)

SQLAlchemy现在有一篇关于如何使用ping对连接的新鲜度表示悲观的文章:

http://docs.sqlalchemy.org/en/latest/core/pooling.html#disconnect-handling-pessimistic

从那里开始

from sqlalchemy import exc
from sqlalchemy import event
from sqlalchemy.pool import Pool

@event.listens_for(Pool, "checkout")
def ping_connection(dbapi_connection, connection_record, connection_proxy):
    cursor = dbapi_connection.cursor()
    try:
        cursor.execute("SELECT 1")
    except:
        # optional - dispose the whole pool
        # instead of invalidating one at a time
        # connection_proxy._pool.dispose()

        # raise DisconnectionError - pool will try
        # connecting again up to three times before raising.
        raise exc.DisconnectionError()
    cursor.close()

并进行测试以确保上述功能正常工作:

from sqlalchemy import create_engine
e = create_engine("mysql://scott:tiger@localhost/test", echo_pool=True)
c1 = e.connect()
c2 = e.connect()
c3 = e.connect()
c1.close()
c2.close()
c3.close()

# pool size is now three.

print "Restart the server"
raw_input()

for i in xrange(10):
    c = e.connect()
    print c.execute("select 1").fetchall()
    c.close()

相关问题 更多 >