python - Flask、SQLAlchemy 和 MySQL Server 已经消失

标签 python mysql flask sqlalchemy mariadb

我的 Flask 应用程序中有一个到 MariaDB (MySQL) 服务器的 SQLAlchemy 连接。我使用范围 session ,并在应用程序上下文拆卸时删除 session 。

engine = create_engine(config.SQLALCHEMY_DATABASE_URI, pool_recycle=3600, isolation_level='READ_COMMITTED')
db_session = scoped_session(sessionmaker(autocommit=True, bind=engine))

@app.teardown_appcontext
def shutdown_session(exception=None):
    db_session.remove()

我还使用 uwsgi 和 8 个 worker 将我的应用程序绑定(bind)到 nginx。

有时我在请求期间收到错误“MySQL 服务器已消失”。当我重复请求时,我没有错误,但如果我再次重复,我又会出错。多次重复请求后,问题消失。 它发生在应用程序重新启动后(并非总是如此),有时在 MySQL 重新启动后发生。

This答案建议在每次使用后关闭 session ,我认为在 teardown_appcontext 上删除 session 是一回事。

我也手动试过rollback session , 但它没有帮助。

最佳答案

以下解决方案适合我。服务器连接错误在自定义 session 和查询(用于 ORM 查询)类的方法中处理。

from sqlalchemy import exc, create_engine, MetaData
from sqlalchemy.orm import scoped_session, sessionmaker, Session, Query

MAX_RETRIES = 2

class RetryQuery(Query):
    def _execute_and_instances(self, *args, **kwargs):
        retry = MAX_RETRIES
        while retry:
            retry -= 1
            try:
                return super(RetryQuery, self)._execute_and_instances(*args, **kwargs)
            except exc.SQLAlchemyError as e:
                if e.orig.args[0] in (2006, 2013, 2014, 2045, 2055) and retry and e.connection_invalidated:
                    continue
                else:
                    raise


class RetrySession(Session):
    def __init__(self, *args, **kwargs):
        kwargs['query_cls'] = RetryQuery
        super(RetrySession, self).__init__(*args, **kwargs)

    def execute(self, *args, **kwargs):
        retry = MAX_RETRIES
        while retry:
            retry -= 1
            try:
                return super(ReconnSession, self).execute(*args, **kwargs)
            except exc.SQLAlchemyError as e:
                if e.orig.args[0] in (2006, 2013, 2014, 2045, 2055) and retry and e.connection_invalidated:
                    continue
                else:
                    raise


engine = create_engine(config.SQLALCHEMY_DATABASE_URI, pool_recycle=3600, isolation_level='READ_COMMITTED')
db_session = scoped_session(class_=RetrySession, sessionmaker(autocommit=True, bind=engine))

db_session.execute("SELECT col FROM table")
db_session.query(User).all()

关于python - Flask、SQLAlchemy 和 MySQL Server 已经消失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35608542/

相关文章:

python - 找到两个乘以 20 的整数。我可以让这段代码更多 "pythonic"吗?

php - 使用 mySQL 和 PHP 每 5 秒更新一次 HTML 表?

php - 本地主机上的 mysql_connect()

python - 从 SQLalchemy 和 Flask 中的相关列表中查询

python - 在 HTML 中的 url_for 上发送 GET 参数

python - 事后将成员函数添加到 Boost Python 类?

python - 花式索引 numpy 矩阵 : one element per row

python - 如何从数据框中找到句子中单词和字符的最大数量?

php - 使用数据库列表项检查列表框中的列表项

python - 如何从 Flask 提供 create-react-app 服务?