Flask-sqlalchemy在重新启动数据库服务器后丢失连接

时间:2016-01-16 14:29:58

标签: postgresql flask sqlalchemy flask-sqlalchemy psycopg2

我在我的应用程序中使用flask-sqlalchemy。 DB是postgresql 9.3。 我有简单的db,model和view初始化:

from config import *
from flask import Flask, request, render_template
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://%s:%s@%s/%s' % (DB_USER, DB_PASSWORD, HOST, DB_NAME)
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    login = db.Column(db.String(255), unique=True, index=True, nullable=False)

db.create_all()
db.session.commit()

@app.route('/users/')
def users():
    users = User.query.all()
    return '1'

一切正常。但是当DB服务器重新启动(sudo service postgresql restart)时,在第一次请求/users/时我获得了sqlalchemy.exc.OperationalError

OperationalError: (psycopg2.OperationalError) terminating connection due to administrator command
SSL connection has been closed unexpectedly
 [SQL: ....

有没有办法在视图中更新连接,或者以另一种方式设置flask-sqlalchemy以自动续订连接?

更新。

我最终使用了清晰的SQLAlchemy,为每个视图声明了引擎,元数据和db_session,我非常需要它。

这不是问题的解决方案,只是一个' hack'。

所以问题是开放的。我相信,为此找到解决方案会很好:)

2 个答案:

答案 0 :(得分:7)

SQLAlchemy documentation解释了默认行为是乐观地处理断开连接。您是否尝试过其他请求 - 连接应该重新建立?我刚刚使用Flask / Postgres / Windows项目对其进行了测试,但它确实有效。

在使用ORM会话的典型Web应用程序中,上述条件对应于单个请求失败并出现500错误,然后Web应用程序正常继续执行。因此,该方法是“乐观的”,因为不会预期频繁的数据库重启。

如果要在连接尝试之前检查连接状态,则需要编写以悲观方式处理断开连接的代码。以下示例代码在文档中提供:

$formElementManager->get('FormWithRoleSelect')

以下是PyCharm调试器中捕获事件的一些屏幕截图:

Windows 7(Postgres 9.4,Flask 0.10.1,SQLAlchemy 1.0.11,Flask-SQLAlchemy 2.1和psycopg 2.6.1)

在第一个数据库请求enter image description here db restart 之后 enter image description here

Ubuntu 14.04(Postgres 9.4,Flask 0.10.1,SQLAlchemy 1.0.8,Flask-SQLAlchemy 2.0和psycopg 2.5.5)

在第一个数据库请求enter image description here 数据库重启后 enter image description here

答案 1 :(得分:0)

在飞机SQLAlchemy中,您可以在调用create_engine函数来解决此问题时添加pool_pre_ping=True kwarg

使用Flask-SQLAlchemy时,可以使用相同的参数,但需要将其作为dict传递给engine_options kwarg

app.db = SQLAlchemy(app, engine_options={"pool_pre_ping": True})