应用程序启动(或重新启动)后第一分钟,我在 Flask 应用程序中的 SQLalchemy 遇到问题。 它看起来像是某种记录器异常:
sqlalchemy.exc.OperationalError:(MySQLdb._exceptions.OperationalError)(2006,'MySQL服务器已经消失')<---- most often one
sqlalchemy.exc.ResourceClosedError:此结果对象不返回行。已经自动关闭了。
sqlalchemy.exc.NoSuchColumnError:“无法在行中找到列‘users.id’的列”
sqlalchemy.exc.NoSuchColumnError:“无法在行中找到列‘ payments.id ’的列”
sqlalchemy.exc.OperationalError:(MySQLdb._exceptions.OperationalError)(2013,“查询期间丢失与 MySQL 服务器的连接”)
然后一切恢复正常。这不是一个关键问题,但很烦人。
我尝试在应用程序启动时运行预热查询:
with app.app_context():
for _ in range(5):
try:
db.session.execute(statement)
logger.info("DB connection is successfully established")
return
except Exception as e:
logger.warning(e)
time.sleep(1)
raise Exception("Couldn't establish a DB connection")
它通过得很好,但后来我看到了同样的问题。
它不会发生在开发环境中,只会发生在 Flask 应用程序在 uwsgi 服务器上运行的生产环境中。有办法解决吗?
更新:连接 URI 如下所示:
"mysql+mysqldb://user:password@localhost/mydb?unix_socket=/var/run/mysqld/mysqld.sock"
似乎如何正确设置 Flask + uWSGI + SQLAlchemy 以避免数据库连接问题对他们有用。这是答案的复制粘贴,只是为了避免“仅链接答案”。我仍然建议任何提出这个问题的人参考上面链接的原始答案。
SQLAlchemy 手册提供了两个如何解决此问题的示例:使用连接池进行多处理。涉及 Engine.dispose() 的第一种方法可以按照 Hett 的建议使用 uwsgidecorators.postfork 来实现 - 如果仅涉及默认绑定,则简单的示例应该可以工作:
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = "postgres:///test"
db.init_app(app)
def _dispose_db_pool():
with app.app_context():
db.engine.dispose()
try:
from uwsgidecorators import postfork
postfork(_dispose_db_pool)
except ImportError:
# Implement fallback when running outside of uwsgi...
raise
return app
元:我根据OP的评论
将此作为答案发布