从syn中删除SQLAlchemy会话

2024-05-08 11:33:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个flaskrestapi,用gunicorn/nginx堆栈运行。对于运行API的每个线程,都会设置一次全局SQLAlchemy会话。我设置了一个端点/test/来运行API的单元测试。一个测试发出POST请求以向数据库中添加内容,然后有一个finally:子句来清理:

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()

问题是,发出POST请求的线程现在在其会话中有一个“test POST”对象,但是数据库没有这样的对象,因为运行测试的线程从数据库中删除了该对象。因此,当我向服务器发出GET请求时,大约四分之一的时间(我有四个gunicorn工作人员),我得到了“test post”对象,四分之三没有。这是因为每个线程都有自己的session对象,它们正在变得不同步,但我真的不知道该怎么做。。。。在

以下是我的SQLAlchemy会话的设置:

^{pr2}$

Tags: 对象testapi数据库jsonurldatasqlalchemy
2条回答

明白了。我所做的是在我的应用程序的init_u.py中为请求添加一个setup和teardown:

@app.before_request
def startup_session():
    db.session = db.connectSQLAlchemy()

@app.teardown_request
def shutdown_session(exception=None): 
    db.session.close()

仍在我的会话中使用全局数据库对象:

^{pr2}$

scoped_session处理不同的线程,我想。。。在

如果出于某种原因,这是一种糟糕的方法,请给出建议。=c)

请使用flask sqlalchemy如果您正在使用flask,它会为您处理会话的生命周期。在

如果您坚持自己做,正确的模式是为每个请求创建一个会话,而不是使用全局会话。你应该这么做

Session = scoped_session(session_factory, scopefunc=flask._app_ctx_stack.__ident_func__)
return Session

而不是

^{pr2}$

然后去做

session = Session()

每次你需要治疗的时候。由于scoped_session和{},这将在每个请求中返回一个不同的会话,但在同一个请求中返回相同的会话。在

相关问题 更多 >