RuntimeError: Trabajo afuera del contexto de aplicación. con app.app_context () no resolver la cuestión

votos
0

Estoy tratando de ejecutar un bucle de tiempo por tener un grupo de procesos de trabajo en ella usando pool.map. El bucle es una parte de una función de vista que he colocado en una nueva función de modo que pueda pasar a pool.map. Pero esto arroja el error -

RuntimeError: Trabajo afuera del contexto de aplicación.

Esto significa típicamente los que se intentaron utilizar la funcionalidad que necesita para interactuar con el objeto de la aplicación actual de alguna manera. Para solucionar esto, establecer un contexto de aplicación con app.app_context (). Consulte la documentación para obtener más información.

Hice la llamada a método en un with app.app_context()(como se ha mencionado aquí ). Pero el error no desapareció. Por favor, dime cómo puedo resolver este 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)

Esto es donde uso multiprocesamiento, y donde I usando with app.app_context():(Esta es una parte de la misma función, 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

Creo que el g.cnxn.commit()que está causando este problema, ya que está expuesta por el contexto de aplicación, pero no estoy seguro. ¡Por favor ayuda!

Publicado el 14/02/2020 a las 00:03
fuente por usuario
En otros idiomas...                            


1 respuestas

votos
1

Como se indica en el matraz de documentos , el contexto aplicación no está disponible fuera de una solicitud que es lo que sucede cuando el loopTaskse ejecuta en un proceso diferente. Considerar la aprobación de la instancia de aplicación para la loopTaskfunción y envolver las secciones del código debajo de ella que utilizan el gobjeto dentro de su espacio de nombres con el bloque. Realmente no necesita el withinterior de bloques de su view_functionpuesto un contexto aplicación ya existe en la solicitud.

EDIT: Debido a que estamos configuración de una conexión db antes de cada solicitud, vamos a obtuvieron con una test_request_context. Puede leer más sobre él aquí . Está destinado para la prueba, pero para nuestros propósitos, que va a permitirnos tener una conexión db en el proceso generado.

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

Esto significa, entonces los withcambios de bloque 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()

Esto debería hacer el truco, pero lo ideal es que debe tener la configuración de la conexión db en una función podemos reutilizar en nuestro loopTask. De esa manera, no necesitaría el test_request_contexty utilizar app_contexten su lugar.

Respondida el 14/02/2020 a las 00:41
fuente por usuario

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