【问题标题】:Search 2 tables simultaneously using flask-executor使用烧瓶执行器同时搜索 2 个表
【发布时间】:2020-05-25 15:51:41
【问题描述】:

我有 2 个带有索引的大型 postgres 表,以便我可以对每个表执行全文搜索。 通常,它们看起来像:

class Post_1(db.Model):
    query_class = PostQuery
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    content = db.Column(db.Text)
    datestamp = db.Column(db.Float)
    search_vector = db.Column(TSVectorType('title', 'content'))

和

class Post_2(db.Model):
    query_class = PostQuery
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String)
    content = db.Column(db.Text)
    datestamp = db.Column(db.Float)
    search_vector = db.Column(TSVectorType('title', 'content'))

在我的烧瓶应用程序中,要获取其中一个表中具有特定关键字的文档,我会这样做:

Post_1.query.search(keyword).\
order_by(Post_1.datestamp.desc()).limit(1)

由于我想在两个表上同时运行相同的搜索,我想使用flask-executor并编写了以下代码:

from flask_executor import Executor
executor = Executor(app)
futures=[]
keyword = "covid"

future=executor.submit(Post_1.query.search(keyword).\
order_by(Post_1.datestamp.desc()).limit(1))
futures.append(future)
future = executor.submit(Post_2.query.search(keyword).\
order_by(Post_2.datestamp.desc()).limit(1))
futures.append(future)

这不起作用,我收到以下错误: RuntimeError:当请求上下文在堆栈上时,此装饰器只能在本地范围内使用。例如在视图函数中。

谁能帮帮我?

【问题讨论】:

    标签: flask sqlalchemy


    【解决方案1】:

    您遇到的错误是因为 flask-executor 旨在在视图函数中运行任务 - 即作为用户请求的一部分。您在视图之外运行代码(即,在用户与应用程序交互时通常存在的范围之外)。

    您是否需要这样做,或者这只是测试的一部分?如果你做这样的事情,只是为了测试一下:

    @app.route('/test')
    def testroute():
        future=executor.submit(Post_1.query.search(keyword).\
        order_by(Post_1.datestamp.desc()).limit(1))
        futures.append(future)
        future = executor.submit(Post_2.query.search(keyword).\
        order_by(Post_2.datestamp.desc()).limit(1))
        futures.append(future)
    

    那么您应该不会再收到关于在请求上下文之外运行的错误,因为代码将作为请求的一部分运行(即在视图函数内部)。

    附带说明,您提交的 SQLAlchemy 任务不可调用 - 它们不是函数对象。执行器,无论是由 Flask-Executor 创建的还是您可以通过concurrent.futures 获得的普通执行器,都希望您传递一个“可调用”。我怀疑你的代码仍然无法工作,除非它是这样的:

    query = Post_1.query.search(keyword).\
    order_by(Post_1.datestamp.desc()).limit(1).all
    future = executor.submit(query)
    

    注意最后没有括号,因为我想使用可调用对象本身,而不是它返回的结果

    然后执行器将“调用”已传递的对象:

    executor.submit(Post_1.query.search(keyword).\
    order_by(Post_1.datestamp.desc()).limit(1).all()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-11-17
      • 2020-05-18
      • 1970-01-01
      • 2018-01-13
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多