问题 Flask-SQLAlchemy:在回滚无效事务之前无法重新连接


因此,我使用Amazon Web Services RDS运行MySQL服务器并使用Python的Flask框架运行应用程序服务器,并使用Flask-SQLAlchemy与RDS进行交互。

我的应用程序config.py

SQLALCHEMY_DATABASE_URI = '<RDS Host>'
SQLALCHEMY_POOL_RECYCLE = 60

我的__ init __.py

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy

application = Flask(__name__)
application.config.from_object('config')
db = SQLAlchemy(application)

我有我的主要application.py

from flask import Flask
from application import db
import flask.ext.restless
from application.models import Person

application = Flask(__name__)
application.debug=True
db.init_app(application)

@application.route('/')
def index():
    return "Hello, World!"

manager = flask.ext.restless.APIManager(application, flask_sqlalchemy_db=db)
manager.create_api(Person, methods=['GET','POST', 'DELETE'])

if __name__ == '__main__':
    application.run(host='0.0.0.0')

models.py

class Person(db.Model):
    __bind_key__= 'people'
    id = db.Column(db.Integer, primary_key=True)
    firstName = db.Column(db.String(80))
    lastName = db.Column(db.String(80))
    email = db.Column(db.String(80))

    def __init__(self, firstName=None, lastName=None, email=None):
        self.firstName = firstName
        self.lastName = lastName
        self.email = email

然后我创建了一个脚本来填充数据库,以便在数据库创建和应用程序启动后进行测试:

from application import db
from application.models import Person

person = Person('Bob', 'Jones', 'bob@website.net')
db.session.add(person)
db.session.commit()

一旦我用db.drop_all()和db.create_all()重置数据库,我启动application.py,然后运行脚本来填充数据库。

服务器将以正确的JSON响应,但如果我回来并在几小时后检查它,我会收到我需要回滚的错误,或者有时候MySQL服务器已经消失的2006错误。

人们建议我更改MySQL服务器上的超时设置但是没有修复任何东西。这是我的设置:

innodb_lock_wait_timeout = 3000
max_allowed_packet       = 65536
net_write_timeout        = 300
wait_timeout             = 300

然后,当我查看RDS监视器时,它显示MySQL服务器保持连接打开很长一段时间,直到超时。现在纠正我,如果我错了,但是在完成之后不应该关闭连接?似乎应用程序服务器一直确保数据库连接存在,然后当MySQL服务器超时时,Flask / Flask-SQLAlchemy会抛出错误并使用它关闭应用程序服务器。

任何建议表示赞赏,谢谢!


1212
2018-06-29 17:30


起源



答案:


我想它是什么添加的

db.init_app(application)

在application.py中,从那以后没有出现错误。


9
2017-07-01 01:54



他在这里: db = SQLAlchemy(application)。你做的是重新初始化。 - Kanstantsin Kamkou
@KanstantsinKamkou是的,但是我有相同的设置,这个额外的init也为我修复了它。很有趣,看看为什么它修复它。 - Leon Overweel
@LeonOverweel在Original Post的情况下,它帮助的原因是因为他用一个新的Flask实例覆盖了他的应用程序定义(名称)在application.py的第6行 - Chockomonkey
我关闭了我的应用程序并重新启动了应用程序。它和平地工作! - SkillFull
我已将此行添加到我的服务器,但它仍然有同样的问题。谁能帮我? - Frank


答案:


我想它是什么添加的

db.init_app(application)

在application.py中,从那以后没有出现错误。


9
2017-07-01 01:54



他在这里: db = SQLAlchemy(application)。你做的是重新初始化。 - Kanstantsin Kamkou
@KanstantsinKamkou是的,但是我有相同的设置,这个额外的init也为我修复了它。很有趣,看看为什么它修复它。 - Leon Overweel
@LeonOverweel在Original Post的情况下,它帮助的原因是因为他用一个新的Flask实例覆盖了他的应用程序定义(名称)在application.py的第6行 - Chockomonkey
我关闭了我的应用程序并重新启动了应用程序。它和平地工作! - SkillFull
我已将此行添加到我的服务器,但它仍然有同样的问题。谁能帮我? - Frank


每次检查回滚与否都很麻烦..

我做了插入,更新需要提交的功能。

@app.teardown_request
def session_clear(exception=None):
    Session.remove()
    if exception and Session.is_active:
        Session.rollback()

3
2017-07-07 05:07



烧瓶的SQLAlchemy 不 它适合你。 - Kanstantsin Kamkou
哦谢谢!!。我不知道,但我不使用flask-sqlalchemy来减少包依赖 - leejaycoke
@leejaycoke我使用原始sqlalchemy并且我在Flask-Admin遇到长时间后需要回滚的状态时遇到问题。我有一个 Session.remove() 拆解但明天会尝试添加此例外部分 - Busturdust
@leejaycoke这个问题是专门询问Flask-SQLAlchemy。如果不相关,您应该删除答案。 - Nathan Wailes


或者,在填充数据库的脚本末尾使用它:

db.session.close()

这应该可以防止那些恼人的“MySQL服务器已经消失”的错误。


0
2017-07-06 15:32



我试过这个,但它没有帮助,我认为它没有用,因为Flask-SQLAlchemy(而不仅仅是SQLAlchemy)已经为你关闭了连接。我只是正确地初始化它。自从我调用init_app以来没有出现过错误。但是感谢您的反馈! - internetwhy
这可能会帮助别人以后!?我不得不使用 with db.session.no_autoflush: 在Flask中修复一些古怪的东西。结果我的PaaS(Heroku)磕磕绊绊。放置 db.session.close() 在“with”语句之前修复了问题。不爱,但事情正在发挥作用。 - Marc