webentwicklung-frage-antwort-db.com.de

Flask-SQLAlchemy: Verbindung kann nicht wiederhergestellt werden, bis eine ungültige Transaktion rückgängig gemacht wird

Also verwende ich Amazon Web Services RDS, um einen MySQL-Server auszuführen, und verwende Pythons Flask-Framework, um den Anwendungsserver auszuführen, und Flask-SQLAlchemy, um mit dem RDS zu kommunizieren.

Meine App config.py

SQLALCHEMY_DATABASE_URI = '<RDS Host>'
SQLALCHEMY_POOL_RECYCLE = 60

Meine __ init __.py

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

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

Ich habe meine Hauptanwendung.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 __== '__main__':
    application.run(Host='0.0.0.0')

Die 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

Ich habe dann ein Skript zum Auffüllen der Datenbank zu Testzwecken nach der Erstellung der Datenbank und dem Start der App:

from application import db
from application.models import Person

person = Person('Bob', 'Jones', '[email protected]')
db.session.add(person)
db.session.commit()

Nachdem ich die Datenbank mit db.drop_all () und db.create_all () zurückgesetzt habe, starte ich die Datei application.py und dann das Skript, um die Datenbank aufzufüllen.

Der Server antwortet mit korrektem JSON, aber wenn ich später zurückkomme und nachprüfe, erhalte ich den Fehler, den ich zurücksetzen muss, oder manchmal den 2006-Fehler, den der MySQL-Server entfernt hat.

Die Leute schlugen vor, dass ich die Timeout-Einstellungen auf dem MySQL-Server ändere, aber das hat nichts behoben. Hier sind meine Einstellungen:

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

Wenn ich dann den RDS-Monitor anschaue, zeigt er, dass der MySQL-Server die Verbindung für einige Zeit offen hielt, bis das Zeitlimit überschritten wurde. Nun korrigieren Sie mich, wenn ich falsch liege, aber sollte die Verbindung nicht geschlossen werden, nachdem sie beendet ist? Anscheinend stellt der Anwendungsserver sicher, dass die Datenbankverbindung besteht, und wenn der MySQL-Server das Zeitlimit überschreitet, gibt Flask/Flask-SQLAlchemy einen Fehler aus und bricht den Anwendungsserver mit sich.

Anregungen sind dankbar, danke!

12
internetwhy

Ich denke, was hat es hinzugefügt?

db.init_app(application)

in application.py hatte der Fehler seitdem nicht mehr.

8
internetwhy

Jedes Mal, wenn ein Rollback durchgeführt wird oder nicht, ist mühsam.

Ich habe Einfügungs- und Aktualisierungsfunktionen erstellt, die ein Commit erfordern.

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

Hier fehlt die Pool-Wiederverwendung, da MySql die Sitzung nach einiger Zeit schließt, sodass Sie die Pool-Wiederverwendung hinzufügen müssen, damit die Verbindungen im Pool nach Ablauf der Pool-Wiederverwendungszeit wiederhergestellt werden.

app.config['SQLALCHEMY_POOL_RECYCLE'] = 3600

0