Django 3.0 ajoute le support asgi / async et avec lui une garde autour de faire des requêtes synchrones dans un contexte async . Parallèlement, IPython vient d'ajouter un support asynchrone / attente de niveau supérieur , qui semble exécuter toute la session d'interpréteur à l'intérieur d'une boucle d'événements par défaut.
Malheureusement, la combinaison de ces deux grands ajouts signifie que toute opération django ORM dans un ordinateur portable jupyter provoque une SynchronousOnlyOperation
exception:
SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
Comme l'indique le message d'exception, il est possible d'envelopper chaque appel ORM de la sync_to_async()
même manière:
images = await sync_to_async(Image.objects.all)()
mais ce n'est pas très pratique, en particulier pour les champs connexes qui seraient généralement résolus implicitement lors de la recherche d'attributs.
(J'ai essayé la %autoawait off
magie mais cela n'a pas fonctionné, d'un rapide coup d'œil aux documents, je suppose que c'est parce que les ipykernels s'exécutent toujours dans une boucle asyncio)
Existe-t-il un moyen de désactiver la synchronisation dans la vérification du contexte asynchrone dans Django ou d'exécuter un ipykernel dans un contexte synchrone?
Pour le contexte: j'ai écrit un package de science des données qui utilise django comme serveur principal mais expose également une interface basée sur jupyter au-dessus de l'ORM qui vous permet de nettoyer / annoter des données, de suivre des expériences d'apprentissage automatique et d'exécuter des tâches de formation dans un cahier jupyter .
la source
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
. J'ai essayé à l'intérieur de jupyter et j'ai également ajouté à settings.py. Mais mon jupyter donne toujours une erreurPour l'instant, je prévois d'utiliser une version forkée de django avec un nouveau paramètre pour ignorer la vérification async_unsafe . Une fois que l'ORM aura obtenu un support asynchrone, je devrai probablement réécrire mon projet pour le prendre en charge et supprimer le drapeau.
EDIT: il y a maintenant un PR pour ajouter une variable env (
DJANGO_ALLOW_ASYNC_UNSAFE
) pour désactiver la vérification ( https://github.com/django/django/pull/12172 )la source