0

我有一个修改数据库的操作,非常耗时,是写在路由中的,要等该操作执行完路由才会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"

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

2017-12-05 提问
2 个回答
1

已采纳

因为你用了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的搭配可以自己网上查查

0

碰巧,我前几天在写《基于 flask-socketio 的 CRUD 操作初探》遇到过这样的问题,这是因为你的 test() 函数里的 Plan ,也就是定义数据库的类,没有在 flask 的应用上下文里。肯定会报错。

撰写答案

推广链接