RuntimeError: al di fuori di lavoro del contesto applicativo. con app.app_context () non risolvere il problema

voti
0

Sto cercando di eseguire un ciclo di tempo per avere un pool di lavoro processi su di esso utilizzando pool.map. Il loop è una parte di una funzione di visualizzazione che ho messo in una nuova funzione in modo che possa passare alla pool.map. Ma questo genera l'errore -

RuntimeError: al di fuori di lavoro del contesto applicativo.

Di solito, ciò significa che si è tentato di utilizzare la funzionalità che aveva bisogno di interfacciarsi con l'oggetto applicazione corrente in qualche modo. Per risolvere questo problema, impostare un contesto di un'applicazione con app.app_context (). Vedere la documentazione per ulteriori informazioni.

Ho fatto mettere la chiamata metodo in un with app.app_context()(come detto qui ). Ma l'errore non è andato via. Ti prego, dimmi come posso risolvere questo problema.

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

Questo è dove io uso multiprocessing, e dove utilizzare with app.app_context():(Questa è una parte della stessa funzione, 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

Credo che la g.cnxn.commit()sta causando questo problema dal momento che è esposto dal contesto di applicazione, ma non sono sicuro. Per favore aiuto!

È pubblicato 13/02/2020 alle 22:03
fonte dall'utente
In altre lingue...                            


1 risposte

voti
1

Come indicato nel pallone documenti , il contesto applicazione non è disponibile al di fuori di una richiesta che è ciò che accade quando loopTaskviene eseguito in un processo differente. Considerate che passa l'istanza app per la loopTaskfunzione di e avvolgere le sezioni del codice di sotto di essa che utilizzano l' goggetto spazio dei nomi all'interno della vostra con il blocco. Non si ha realmente bisogno il withblocco all'interno del vostro view_functionpoiché un contesto applicazione esiste già durante la richiesta.

EDIT: Perché stiamo impostare una connessione db prima di ogni richiesta, diamo ottenuto con una test_request_context. Si può leggere di più su di esso qui . E 'pensato per testare, ma per i nostri scopi, che sarà ci permettono di avere una connessione db nel processo generato.

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

Ciò significa quindi le withmodifiche blocco a:

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

Questo dovrebbe fare il trucco ma idealmente, dovremmo avere la configurazione della connessione db in una funzione possiamo riutilizzare nel nostro loopTask. In questo modo, non ci sarebbe bisogno del test_request_contexte utilizzare app_contextinvece.

Risposto il 13/02/2020 a 22:41
fonte dall'utente

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