flask路由中使用threading报错

creazyloser
  • 36

我有一个修改数据库的操作,非常耗时,是写在路由中的,要等该操作执行完路由才会return。于是我试着用了一下threading模块,起了一个线程去执行该操作,而无需等待它执行完,路由直接返回状态。但是这样用的时候始终报错图片描述

数据库连接用的SQLAlchemy,写了一个最简单的例子,求大家帮我看看问题出在哪里
定义model:

class Plan(db.Model):
    __tablename__ = 'opt_version_plans'

    planid = db.Column(db.Integer,primary_key=True)
    planname = db.Column(db.String(255))
    jobname = db.Column(db.String(255))
    branch = db.Column(db.String(32))

定义一个函数:

def test():
    time.sleep(20)
    p = Plan.query.get(1)
    print p.planname

路由:

@app.route('/')
def index():
    t = threading.Thread(target=test)
    t.start()
    return "helloworld"

请求/就会出现上面的那个报错,网上查了查,还是不懂原因,请问用这种方式,我该怎么做?

回复
阅读 4.1k
2 个回答
✓ 已被采纳

因为你用了flask-sqlalchemy扩展,而且你新开了一个线程执行test方法,这个线程已经脱离了 Flask app 的应用上下文,如果非要按照你上面的例子的话,可以这样修改

def test():
    time.sleep(20)
    with app.app_context():
        p = Plan.query.get(1)
    print p.planname

另外,你的思路没错,但是一个通用的解决办法是使用Celery将你那个耗时的任务异步执行。

@celery.task
def test():
    p = Plan.query.get(1)
    print p.planname
    return p

@app.route('/')
def index():
    task = test.delay()  #: 异步执行
    return "hello world"

具体CeleryFlask的搭配可以自己网上查查

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏