Я пишу приложение Flask и пытаюсь вставить многопоточную реализацию для определенных функций, связанных с сервером. Я заметил это странное поведение, поэтому хотел понять, почему это происходит и как с этим справиться. У меня такой код:
from flask_login import current_user, login_required
import threading
posts = Blueprint('posts', __name__)
@posts.route("/foo")
@login_required
def foo():
print(current_user)
thread = threading.Thread(target=goo)
thread.start()
thread.join()
return
def goo():
print(current_user)
# ...
Основной процесс правильно печатает current_user
, а дочерний поток - None
.
User('Username1', '[email protected]', 'Username1-ProfilePic.jpg')
None
Почему это происходит? Как я могу получить current_user
также в дочернем процессе? Я попытался передать его как аргумент goo
, но по-прежнему получаю такое же поведение.
Я нашел этот пост, но не могу понять, как гарантировать, что контекст не меняется в этом ситуации, поэтому я попытался привести более простой пример.
Частично рабочий обходной путь
Я попытался передать в качестве параметра также недавно созданный объект User
, заполненный данными из current_user
def foo():
# ...
user = User.query.filter_by(username=current_user.username).first_or_404()
thread = threading.Thread(target=goo, args=[user])
# ...
def goo(user):
print(user)
# ...
И он правильно печатает информацию о текущем пользователе. Но поскольку внутри goo
я также выполняю операции с базой данных, я получаю следующую ошибку:
RuntimeError: приложение не найдено. Либо работайте внутри функции просмотра, либо проталкивайте контекст приложения. См. http://flask-sqlalchemy.pocoo.org/contexts/.
Итак, как я и подозревал, я предполагаю, что это проблема контекста.
Я попытался также вставить это внутрь goo
, как подсказала ошибка:
def goo():
from myapp import create_app
app = create_app()
app.app_context().push()
# ... database access
Но я все равно получаю те же ошибки, и если я пытаюсь напечатать current_user
, я получаю None
.
Как передать старый контекст новому потоку? Или создать новый?
with app.app_context():
. - person Cihan   schedule 10.10.2020goo
в операторwith create_app().app_context():
, и поведение осталось прежним. (Я использовалcreate_app()
, поскольку использую Blueprints, у меня нет прямой ссылки наapp
, но у меня такое чувство, что то, что я сделал, было совершенно неправильным) - person Robb1   schedule 10.10.2020