Comment utiliser django 3.0 ORM dans un bloc-notes Jupyter sans déclencher la vérification du contexte asynchrone?

24

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 SynchronousOnlyOperationexception:

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 offmagie 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 .

michalwols
la source

Réponses:

18

Ça marche pour moi

os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"

BTW, je démarre mon carnet en utilisant la commande

./manage.py shell_plus --notebook

J'espère que cela aide

Wojtas Koziej
la source
J'ai essayé ça. il montre toujours l'erreur dans jupyter. Où dois-je mettre 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 erreur
Santhosh Yedidi
2
Je l'ai mis dans le cahier
Wojtas Koziej
@michalwols réponse a fonctionné pour moi
Santhosh Yedidi
@SanthoshYedidi le fait dans le cli. Exportez la variable avant d'exécuter le serveur jupyter.
Siddharth Pant
travaillé pour moi aussi. il suffit de l'ajouter au settings.py et d'exécuter shell_plus sur le portable
Shekhar
6

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

michalwols
la source
1
Ce changement est maintenant prévu pour 3.0.1
Sayse
Cette solution a fonctionné pour moi. merci
Santhosh Yedidi