RuntimeError: en dehors du travail contexte d'application. avec app.app_context () ne résout pas le problème

voix
0

Je suis en train d'exécuter une boucle beaucoup de temps en ayant un groupe de travail sur les processus à l'aide pool.map. La boucle est une partie d'une fonction d'affichage qui j'ai placé dans une nouvelle fonction afin que je puisse passer à pool.map. Mais cela jette l'erreur -

RuntimeError: en dehors du travail contexte d'application.

Ce que signifie généralement que vous avez essayé d'utiliser la fonctionnalité nécessaire pour que l'interface avec l'objet de l'application en cours d'une certaine façon. Pour résoudre ce problème, mettre en place un contexte d'application avec app.app_context (). Consultez la documentation pour plus d'informations.

Je l'ai fait passer l'appel de la méthode dans un with app.app_context()(comme mentionné ici ). Mais l'erreur ne disparaît pas. S'il vous plaît dites - moi comment je peux résoudre ce problème.

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

C'est là que j'utilise multitraitement, et où je l' aide with app.app_context():(Ceci est une partie de la même fonction, 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

Je crois que le g.cnxn.commit()est à l' origine de cette question car elle est exposée par le contexte d'application mais je ne suis pas sûr. Aide s'il vous plaît!

Créé 14/02/2020 à 00:03
source utilisateur
Dans d'autres langues...                            


1 réponses

voix
1

Comme indiqué dans les Flask docs , le contexte de l' application est pas disponible en dehors d'une demande qui est ce qui se passe lorsque le loopTaskest exécuté dans un processus différent. Pensez à passer votre instance d'application à la loopTaskfonction et envelopper les sections du code d' application qui utilisent l' gobjet d'espace de noms avec l' intérieur de votre bloc. Ne pas vraiment besoin de l' withintérieur du bloc de votre view_functiondepuis un contexte d'application existe déjà au cours de la demande.

EDIT: Parce que nous mettons en place une connexion db avant chaque demande, nous allons eu avec test_request_context. Vous pouvez en lire davantage ici . Il est destiné à tester mais pour nos fins, il va nous permettre d'avoir une connexion db dans le processus donné naissance.

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

Cela signifie donc les withchangements de bloc à:

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

Cela devrait faire l'affaire , mais idéalement, nous devrions avoir la configuration de la connexion db dans une fonction que nous pouvons réutiliser dans notre loopTask. De cette façon, nous aurions pas besoin test_request_contextet utiliser à la app_contextplace.

Créé 14/02/2020 à 00:41
source utilisateur

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