【发布时间】:2016-10-17 02:46:38
【问题描述】:
我有一个 Flask REST API,使用 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 请求的线程现在在其会话中有一个“测试帖子”对象,但数据库没有这样的对象,因为运行测试的线程从数据库中删除了该对象。因此,当我向服务器发出 GET 请求时,大约 4 次中的 1 次(我有 4 个 gunicorn 工人),我得到了“测试帖子”对象,而 4 次中有 3 次没有。这是因为每个线程都有自己的会话对象,并且它们不同步,但我真的不知道该怎么办......
这是我的 SQLAlchemy 会话设置:
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()
【问题讨论】:
标签: python multithreading session sqlalchemy gunicorn