RuntimeError: în afara contextului de lucru aplicare. cu app.app_context () nu rezolvarea problemei

voturi
0

Am încercat să ruleze o consumatoare de timp bucla de a avea un bazin de procese de lucru pe ea folosind pool.map. Bucla este o parte dintr - o funcție de vedere pe care l - am pus într - o nouă funcție , astfel încât să pot trece - l la pool.map. Dar acest lucru aruncă eroarea -

RuntimeError: în afara contextului de lucru aplicare.

Acest lucru inseamna de regula pe care ați încercat să utilizați funcționalitatea care este nevoie pentru a interfața cu obiectul aplicație curentă într-un fel. Pentru a rezolva acest lucru, creat un context aplicație cu app.app_context (). Consultați documentația pentru mai multe informații.

Am făcut plasa apelul metodei într - un with app.app_context()(așa cum este menționat aici ). Dar eroarea nu a mers departe. Te rog spune - mi cum pot rezolva această problemă.

@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)

Acesta este locul unde am folosesc multiprocesare, și în cazul în care am folosind with app.app_context():(Aceasta este o parte din aceeași funcție, 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

Eu cred că g.cnxn.commit()provoacă această problemă , deoarece acesta este expus de contextul de aplicare , dar nu sunt sigur. Te rog ajuta-ma!

Întrebat 14/02/2020 la 00:03
sursa de către utilizator
În alte limbi...                            


1 răspunsuri

voturi
1

După cum se indică în Flask docs , contextul aplicație nu este disponibilă în afara unei cereri care este ceea ce se întâmplă atunci când loopTaskse execută într - un proces diferit. Luați în considerare trecerea exemplu aplicației la loopTaskfuncția și înfășurați secțiunile codului de sub ea care utilizează gobiectul spațiului de nume din interiorul tau cu bloc. Nu au nevoie într - adevăr withinteriorul blocului de dvs. , view_functiondeoarece există deja un context aplicație în timpul solicitării.

EDIT: Pentru că configurați o conexiune db înainte de fiecare cerere, să primit cu test_request_context. Puteți citi mai multe despre el aici . Este menit pentru testare , dar pentru scopurile noastre, acest lucru va permite să avem o conexiune db în procesul dat naștere.

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

Aceasta înseamnă că atunci withmodificările bloc la:

    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()

Acest lucru ar trebui să facă truc , dar în mod ideal, ar trebui să avem configurarea conexiunii db într - o funcție ne putem refolosi în nostru loopTask. În acest fel, nu am nevoie de test_request_contextși de a folosi în app_contextschimb.

Publicat 14/02/2020 la 00:41
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more