﻿id	summary	reporter	owner	description	type	status	component	version	severity	resolution	keywords	cc	stage	has_patch	needs_docs	needs_tests	needs_better_patch	easy	ui_ux
37218	Fetch modes aren't async-compatible	Jacob Walls	Jacob Walls	"
See [https://dryorm.xterm.info/fetch-mode-async-failure fiddle]:

{{{#!py
from asgiref.sync import async_to_sync
from django.contrib.auth.models import User
from django.db import models


class Person(models.Model):
    name = models.CharField(max_length=100)
    user = models.ForeignKey(User, models.CASCADE)
    

@async_to_sync
async def async_view():
    qs = Person.objects.fetch_mode(models.FETCH_PEERS)
    async for el in qs:
        print(el.user)


def run():
    admin = User.objects.create(username=""admin"")
    instance = Person.objects.create(name='John Doe', user=admin)
    instance2 = Person.objects.create(name='Jane Doe', user=admin)
    async_view()

}}}
{{{#!py
  File ""/app/app/models.py"", line 15, in async_view
    print(el.user)
          ^^^^^^^
  File ""/django-pr/django/db/models/fields/related_descriptors.py"", line 266, in __get__
    instance._state.fetch_mode.fetch(self, instance)
  File ""/django-pr/django/db/models/fetch_modes.py"", line 38, in fetch
    fetcher.fetch_many(instances)
  File ""/django-pr/django/db/models/fields/related_descriptors.py"", line 291, in fetch_many
    prefetch_related_objects(missing_instances, self.field.name)
  File ""/django-pr/django/db/models/query.py"", line 2701, in prefetch_related_objects
    obj_list, additional_lookups = prefetch_one_level(
                                   ^^^^^^^^^^^^^^^^^^^
  File ""/django-pr/django/db/models/query.py"", line 2876, in prefetch_one_level
    all_related_objects = list(rel_qs)
                          ^^^^^^^^^^^^
  File ""/django-pr/django/db/models/query.py"", line 434, in __iter__
    self._fetch_all()
  File ""/django-pr/django/db/models/query.py"", line 2239, in _fetch_all
    self._result_cache = list(self._iterable_class(self))
                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/django-pr/django/db/models/query.py"", line 98, in __iter__
    results = compiler.execute_sql(
              ^^^^^^^^^^^^^^^^^^^^^
  File ""/django-pr/django/db/models/sql/compiler.py"", line 1622, in execute_sql
    cursor = self.connection.cursor()
             ^^^^^^^^^^^^^^^^^^^^^^^^
  File ""/django-pr/django/utils/asyncio.py"", line 24, in inner
    raise SynchronousOnlyOperation(message)
django.core.exceptions.SynchronousOnlyOperation: You cannot call this from an async context - use a thread or sync_to_async.
}}}

We probably need to add `AFETCH_PEERS` and `AFETCH_ONE` fetch modes, and duplicate the `fetch_{one,many}()` methods into `afetch_{one,many}()` on the descriptors.

I can hustle this in before the release candidate if it seems sane."	Bug	assigned	Database layer (models, ORM)	6.1	Normal		fetch modes, async	Adam Johnson Simon Charette	Unreviewed	0	0	0	0	0	0
