SQLAlchemy错误MySQL服务器已经消失

时间:2013-05-02 15:26:34

标签: python mysql sqlalchemy flask

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

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

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)。

谢谢..

5 个答案:

答案 0 :(得分:14)

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()

答案 1 :(得分:0)

来自documentation

您可以使用pool_recycle参数:

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

答案 2 :(得分:0)

我刚遇到同样的问题,这是通过一些努力解决的。希望我的经历对他人有所帮助。

通过一些建议,我使用了连接池并将pool_recycle设置为小于wait_timeout,但它仍然不起作用。

然后,我意识到全局会话可能只是使用相同的连接,并且连接池不起作用。为了避免全局会话,为每个请求生成一个新会话,在处理后由Session.remove()删除。

最后,一切都很好。

答案 3 :(得分:0)

答案 4 :(得分:0)

要记住的另一点是使用数据库初始化手动推送flask应用程序上下文。这应该可以解决问题。

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

app = Flask(__name__)
with app.app_context():
    db.init_app(app)