動態

詳情 返回 返回

django4.2 異步ORM的變化--持續觀察 - 動態 詳情

Django

官網有描述

Django異步的變化

  1. 4.2相比於4.0的變化就是使用sync_to_async
  2. 最大的變化就是可以使用同步和異步互不影響

異步實現

models文件夾下的query文件

class BaseIterable:
    def __init__(
        self, queryset, chunked_fetch=False, chunk_size=GET_ITERATOR_CHUNK_SIZE
    ):
        self.queryset = queryset
        self.chunked_fetch = chunked_fetch
        self.chunk_size = chunk_size

    async def _async_generator(self):
        # Generators don't actually start running until the first time you call
        # next() on them, so make the generator object in the async thread and
        # then repeatedly dispatch to it in a sync thread.
        sync_generator = self.__iter__()

        def next_slice(gen):
            return list(islice(gen, self.chunk_size))

        while True:
            chunk = await sync_to_async(next_slice)(sync_generator)
            for item in chunk:
                yield item
            if len(chunk) < self.chunk_size:
                break

    # __aiter__() is a *synchronous* method that has to then return an
    # *asynchronous* iterator/generator. Thus, nest an async generator inside
    # it.
    # This is a generic iterable converter for now, and is going to suffer a
    # performance penalty on large sets of items due to the cost of crossing
    # over the sync barrier for each chunk. Custom __aiter__() methods should
    # be added to each Iterable subclass, but that needs some work in the
    # Compiler first.
    def __aiter__(self):
        return self._async_generator()


class ModelIterable(BaseIterable):
    """Iterable that yields a model instance for each row."""

    def __iter__(self):
        代碼省略

class QuerySet(AltersData):
    """Represent a lazy database lookup for a set of objects."""

    def __init__(self, model=None, query=None, using=None, hints=None):
        self._iterable_class = ModelIterable

   def __aiter__(self):
      # Remember, __aiter__ itself is synchronous, it's the thing it returns
      # that is async!
      async def generator():
          await sync_to_async(self._fetch_all)()
          for item in self._result_cache:
              yield item

      return generator()

結論

  • 就是__aiter__ 實現了async for 方法,具體的await obj是通過sync_to_async實現
  • 感覺ORM層面的異步和同步區別不大,畢竟在數據連接層面沒有變化
  • 暫時看出來的就這麼多,技術有限,後續繼續跟進
user avatar k8scat 頭像 codexiaosheng 頭像 hunter_58d48c41761b8 頭像
點贊 3 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.