gpt4 book ai didi

python - app.app_context() 的 RuntimeError : Working outside of application context. 无法解决问题

转载 作者:行者123 更新时间:2023-12-01 06:24:50 26 4
gpt4 key购买 nike

我试图通过使用pool.map让进程池在其上工作来运行一个耗时的循环。该循环是 View 函数的一部分,我已将其放置在新函数中,以便可以将其传递给 pool.map。但这会引发错误 -

RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed to interface with the current application object in some way. To solve this, set up an application context with app.app_context(). See the documentation for more information.

我确实将方法调用放在 with app.app_context() 中(如前所述 here )。但错误并没有消失。请告诉我如何解决这个问题。

@app.route('/some_url', methods= ['POST'])
def view_function ():
start_time = time.time()
data = request.get_json()
a = round(data.get('a', '') * data.get('a', ''))
b = round(data.get('b', '') * data.get('b', ''))
c = round(data.get('c', '') * data.get('c', ''))
d = round(data.get('d', '') * data.get('d', ''))

a_id = select.get_id(data.get('property', ''), session['somedata'][1])
some_list, a_ids, loc = AnotherClassInDifferentDir.get_list(a_id, session['somedata'][1])
value = select.get_value(//some arguments)

这是我使用多处理的地方,也是我使用 with app.app_context(): (这是同一函数 view_function 的一部分)-

    with app.app_context():
e = data.get('e', '')
stuff = session['somedata'][1]
pool = Pool(processes = 2)
func = partial(loopTask,e, a_id, a_ids, a, b, c, d, loc, stuff)
stuff_array = [(index, item) for index, item in enumerate(some_list)]
print("stuff_array =", stuff_array)
pool.map(func, stuff_array)
pool.close()
pool.join()

print("--- %s seconds ---" % (time.time() - start_time))
return ''

def loopTask(e, a_ids, a, b, c, d, loc, stuff, stuff_item):

index, s = stuff_item
c_id = document_ids[index]
done = AnotherClassInDifferentDir.work(s)
f = AnotherClassInDifferentDir.more_work(done, a, b, c, d, loc)
if f != '':
update.update_work(//some arguments)
g.cnxn.commit()
if (moreDB.check(//some arguments) ==0):
update.work(//some arguments)
g.cnxn.commit()
else:
pass

我相信 g.cnxn.commit() 导致了此问题,因为它是由应用程序上下文公开的,但我不确定。请帮忙!

编辑

g.cnxn 使用装饰器 @app.before_request

以不同的方法设置
@app.before_request
def connect_to_database():
if request.endpoint != 'static':
if not hasattr(g,'cnxn'):
g.cnxn = pyodbc.connect('DRIVER={{Some Driver}};config1={};config2={};Trusted_connection=yes'.format(app.config['config1'],app.config['config2']))

最佳答案

如 Flask docs 中所示,应用程序上下文在请求之外不可用,这是当 loopTask 在不同进程中运行时发生的情况。考虑将您的应用实例传递给 loopTask 函数,并将其下使用 g 命名空间对象的代码部分包装在 with block 内。实际上不需要在 view_function 中使用 with block ,因为请求期间应用上下文已经存在。

编辑:因为我们在每个请求之前设置数据库连接,所以我们使用 test_request_context。您可以阅读更多相关信息here 。它用于测试,但出于我们的目的,它将允许我们在生成的进程中拥有数据库连接。

def loopTask(e, a_ids, a, b, c, d, loc, stuff, stuff_item, app):  # added app parameter 

index, s = stuff_item
c_id = document_ids[index]

with app.test_request_context('/some_url'):
app.preprocess_request() # triggers 'connect_to_database'

done = AnotherClassInDifferentDir.work(s)
f = AnotherClassInDifferentDir.more_work(done, a, b, c, d, loc)
if f != '':
update.update_work(//some arguments)
g.cnxn.commit()
if (moreDB.check(//some arguments) ==0):
update.work(//some arguments)
g.cnxn.commit()
else:
pass

这意味着 with block 更改为:

    e = data.get('e', '')
stuff = session['somedata'][1]
pool = Pool(processes = 2)
func = partial(loopTask,e, a_id, a_ids, a, b, c, d, loc, stuff, stuff_item)
stuff_array = [(index, item) for index, item in enumerate(some_list)]
print("stuff_array =", stuff_array)
pool.map(func, (stuff_array, app)) # passing the `app` Flask instance here
pool.close()
pool.join()

这应该可以解决问题,但理想情况下,我们应该在一个可以在 loopTask 中重用的函数中设置数据库连接。这样,我们就不需要 test_request_context 并使用 app_context 来代替。

关于python - app.app_context() 的 RuntimeError : Working outside of application context. 无法解决问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60216421/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com