我有一份长期工作来构建分析报告。我想开始工作,给用户一个永久链接,然后允许用户刷新页面以查看他们的报告是否准备就绪。该报告的状态初始化为pending
。作业完成后,我需要将状态保存到ready
。
我使用Python的threading
模块启动了这项工作。问题是,当我保存状态时,我不再处于有效的Flask-SQLAlchemy会话中。这是错误:
RuntimeError: application not registered on db instance and no application bound to current context
以下是代码:
from threading import Thread
from app import db
from app.models import Report
def build():
report = __save_and_detach_report(Report())
thread = Thread(target=__build, args=(report,))
thread.daemon = True
thread.start()
return report.id
def __build(report):
print('starting job')
time.sleep(10)
print('job complete')
__set_report_ready(report)
def __save_and_detach_report(report):
with session_scope() as session:
session.add(report)
session.commit()
session.expunge(report)
return report
def __set_report_ready(report):
with session_scope() as session:
report.ready()
session.merge(report)
@contextmanager
def session_scope():
try:
yield db.session
db.session.commit()
except Exception as e:
print 'Rolling back database'
print e
db.session.rollback()
调用merge
时会抛出错误。
答案 0 :(得分:1)
如果要保存到数据库,则应该打开一个新会话。
我不确定你的session_scope()
是做什么的。我的一个项目中有类似的东西:
@contextmanager
def db_session():
session = Session()
try:
yield session
session.commit()
except:
session.rollback()
raise
finally:
session.close()
然后,在我可以做的一个主题中:
with db_session() as session:
# save to data base