Runtime: Arbeiten außerhalb des Anwendungskontext. mit app.app_context () löst nicht das Problem

stimmen
0

Ich versuche , eine Zeit zu laufen , indem man einen Pool von Prozessen arbeiten daran mit raubend Schleife pool.map. Die Schleife ist ein Teil einer Ansicht Funktion , die ich in einer neuen Funktion gesetzt habe , so dass ich passieren kann es pool.map. Aber dies führt den Fehler -

Runtime: Arbeiten außerhalb des Anwendungskontext.

Diese Regel bedeutet, dass Sie versuchte Funktion zu nutzen, die in irgendeiner Weise mit dem aktuellen Anwendungsobjekt-Schnittstelle benötigt. Um dies zu lösen, einen Anwendungskontext mit app.app_context eingerichtet (). Lesen Sie die Dokumentation für weitere Informationen.

Ich habe den Methodenaufruf in einem Ort with app.app_context()(wie erwähnt hier ). Aber der Fehler nicht weggehen. Bitte sagen Sie mir , wie ich dieses Problem beheben kann.

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

Dies ist , wo ich verwende Multiprocessing, und wo ich mit with app.app_context():(Dies ist ein Teil der gleichen Funktion 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

Ich glaube , die g.cnxn.commit()dieses Problem verursacht , da sie durch den Anwendungskontext ausgesetzt ist , aber ich bin mir nicht sicher. Bitte Hilfe!

Veröffentlicht am 13/02/2020 um 22:03
quelle vom benutzer
In anderen Sprachen...                            


1 antworten

stimmen
1

Wie in den Fläschchen angegeben docs , ist der App Kontext nicht verfügbar außerhalb einer Anfrage , das , was passiert ist , wenn die loopTaskin einem anderen Prozess ausgeführt wird. Betrachten Sie Ihre App - Instanz in die vorbeiziehende loopTaskFunktion und wickeln Sie die Abschnitte des Codes unter, dass die Verwendung gNamespace - Objekt in Ihrem mit Block. Sie brauchen nicht wirklich den withBlock innerhalb Ihrer view_functionda ein App Kontext existiert bereits in der Anfrage.

EDIT: Weil wir die Einrichtung eine DB - Verbindung vor jeder Anforderung auf, lassen Sie sich mit einem bekommt test_request_context. Sie können mehr darüber lesen Sie hier . Es soll den Zweck zu testen , aber für unsere Zwecke, wird es uns erlauben , eine DB - Verbindung in dem erzeugten Prozess zu haben.

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

Darunter ist dann der withBlock Änderungen an:

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

Dies sollte es tun , sondern im Idealfall sollten wir den db Verbindungsaufbau in einer Funktion haben wir in unserem wiederverwenden können loopTask. Auf diese Weise würden wir nicht brauchen test_request_contextund verwenden app_contextstatt.

Beantwortet am 13/02/2020 um 22:41
quelle vom benutzer

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