Ich habe eine Flask REST API, die mit einem Gunicorn/Nginx-Stack ausgeführt wird. Für jeden Thread, auf dem die API ausgeführt wird, wird einmal eine globale SQLAlchemy-Sitzung eingerichtet. Ich habe einen Endpunkt/Test/eingerichtet, um die Komponententests für die API auszuführen. Ein Test eine POST-Anforderung macht, etwas zu der Datenbank hinzuzufügen, hat dann eine endlich: Klausel aufzuräumen:Flask SQLAlchemy Sitzungen nicht synchron
def test_something():
try:
url = "http://myposturl"
data = {"content" : "test post"}
headers = {'content-type': 'application/json'}
result = requests.post(url, json=data, headers=headers).json()
validate(result, myschema)
finally:
db.sqlsession.query(MyTable).filter(MyTable.content == "test post").delete()
db.sqlsession.commit()
Das Problem ist, dass der Thread, auf die die POST-Anforderung gemacht hat jetzt eine „Test-Post“ Objekt in seiner Sitzung, aber die Datenbank hat kein solches Objekt, weil der Thread, auf dem die Tests ausgeführt wurden, dieses Objekt aus der Datenbank löschte. Also, wenn ich eine GET-Anfrage an den Server mache, etwa 1 in 4 Mal (ich habe 4 Gunicorn-Arbeiter), bekomme ich das "Test-Post" -Objekt, und 3 in 4-mal nicht. Das liegt daran, dass die Threads jeweils ihr eigenes Sitzungsobjekt haben und dass sie nicht mehr synchron sind, aber ich weiß nicht, was ich dagegen tun soll.
Hier ist mein Setup für meine SQLAlchemy-Sitzung:
def connectSQLAlchemy():
import sqlalchemy
import sqlalchemy.orm
engine = sqlalchemy.create_engine(connection_string(DBConfig.USER, DBConfig.PASSWORD, DBConfig.HOST, DBConfig.DB))
session_factory = sqlalchemy.orm.sessionmaker(bind=engine)
Session = sqlalchemy.orm.scoped_session(session_factory)
return Session()
# Create a global session for everyone
sqlsession = connectSQLAlchemy()
Ich habe getan, was Sie gesagt haben, und ich habe self.session = db.Session() in der Funktion __init__ für eine neue APIResource (Resource) -Klasse, aber ich habe das gleiche Problem ... Ich füge hinzu etwas an die Datenbank und lösche es in separaten Threads, aber der Adding-Thread merkt sich das Ding. – Scott
@Scott Sie sagen, Sie haben mehrere Threads * innerhalb derselben Anfrage *? – univerio
Nein. Nur die Gunicorn-Fäden. Ich denke, das Problem mit dieser Lösung ist, dass ich die Sitzung am Ende der Anfrage irgendwo abreißen muss. – Scott