Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Django 4.1のAsynchronous

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.
Avatar for Junya Fukuda Junya Fukuda
November 12, 2022

Django 4.1のAsynchronous

talk about "Asynchronous ORM interface, Asynchronous handlers for class-based views".
Nov 12, 2022
DjangoCongress JP 2022 at NIKKEI Conference Room Nikkei Building
https://djangocongress.jp/

Avatar for Junya Fukuda

Junya Fukuda

November 12, 2022
Tweet

More Decks by Junya Fukuda

Other Decks in Technology

Transcript

  1. ( 話 ?) •ڈ೥ͷDjangoCongress JP 2021 ͰͷτʔΫΛΞοϓσʔτ͍ͨ͠ •Django 3.2 ASGI

    ରԠ - ͜Θ͘ͳ͍ asyncio جૅͱ async view ͷ࢖͍ॴ IUUQTMPHNJKQUFDIBSUJDMFT •DjangoͷORM͸ͳͥਖ਼ࣜରԠͰ͸ͳ͍ͷ͔ •΋͔ͨ͠͠Βͦ͏ࢥΘΕͨํ΋͍Βͬ͠ΌΔ͔΋͠Ε·ͤΜʢΘͨ͠
  2. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 2012

    2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  3. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 1.8

    LTS 2015 2012 2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  4. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 1.8

    LTS 1.11 LTS 2.0 2017 2015 2012 2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  5. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 1.8

    LTS 1.11 LTS 2.0 2.2 LTS 3.0 2019 2017 2015 2012 2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  6. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 1.8

    LTS 1.11 LTS 2.0 2.2 LTS 3.0 3.2 LTS 4.0 2021 2019 2017 2015 2012 2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  7. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 1.8

    LTS 1.11 LTS 2.0 2.2 LTS 3.0 3.2 LTS 4.0 4.1 2022 2021 2019 2017 2015 2012 2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  8. - Django ⾮同期対応 2005 Django OSS 1.0 1.4 LTS 1.8

    LTS 1.11 LTS 2.0 2.2 LTS 3.0 3.2 LTS 4.0 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2008 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  9. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    3.0 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2.2 LTS •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  10. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    3.0 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio 2.2 LTS •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  11. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    3.0 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await Python 3.5 2.2 LTS •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  12. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    3.0 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await 2016 Python 3.5 asgiref 1.0 2.2 LTS •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  13. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.0 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  14. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.0 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels asgiref 3.0 •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  15. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels asgiref 3.0 3.0 asgiରԠ •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  16. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels asgiref 3.0 3.0 ؔ਺view asgiରԠ •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  17. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels asgiref 3.0 3.0 asgiରԠ ؔ਺view ΫϥεϏϡʔ ORM IF •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  18. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels asgiref 3.0 3.0 asgiରԠ ؔ਺view ΫϥεϏϡʔ ORM IF •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  19. - Django ⾮同期対応 1.4 LTS 1.8 LTS 1.11 LTS 2.0

    2.2 LTS 3.2 LTS 4.1 4.2 LTS 2023 2022 2021 2019 2017 2015 2012 2014 Python 3.4 asyncio async/await asgiref 1.0 2016 Python 3.5 channels asgiref 3.0 3.0 asgiରԠ ؔ਺view ΫϥεϏϡʔ ORM IF DEP 0009: Async-capable DjangoʢDEP͸DjangoͷPEPʣ •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ
  20. - asyncio 基本 •ඇಉظॲཧͷίʔυΛॻͨ͘Ίͷඪ४ϥΠϒϥϦ •ຖόʔδϣϯਐԽ ߴϨϕϧAPI͕ॆ࣮ - ͱͯ΋ॻ͖΍͍͢ •ෳ਺ͷλεΫΛಉ࣌ʹॲཧ͢Δ •I/Oό΢ϯυͳॲཧʢDBΞΫηε/HTTPϦΫΤετͳͲʣͰޮՌΛൃش

    •async/await ߏจ •λεΫΛొ࿥͢Δasyncio.create_task() - ʮλεΫʯ = ॲཧͩͱࢥ͍ͬͯͩ͘͞ɻ •ॲཧΛฒߦʹ͢Δasyncio.gather() •ྫ֎΍ΩϟϯηϧΛॊೈʹ asyncio.TaskGroup •αʔυύʔςΟͷϥΠϒϥϦΛ࢖͏৔߹ɺඇಉظରԠ͍ͯ͠Δඞཁ͕͋Δ
  21. Django 63- σΟεύο νϟʔ 63-DPOG Ϗϡʔ ϑΥʔϜ ςϯϓϨʔτ Ϟσϧ DjangoϓϩδΣΫτ

    ϒϥ΢β Webαʔό ΞϓϦέʔγϣϯαʔό ϦΫΤ ετ ֎෦Ϧιʔε ϛυϧ ΢ΣΞ Ϩεϙ ϯε
  22. Django 63- σΟεύο νϟʔ 63-DPOG Ϗϡʔ ϑΥʔϜ ςϯϓϨʔτ Ϟσϧ DjangoϓϩδΣΫτ

    ϒϥ΢β Webαʔό ΞϓϦέʔγϣϯαʔό ϦΫΤ ετ ֎෦Ϧιʔε ϛυϧ ΢ΣΞ Ϩεϙ ϯε ʮݱ৔Ͱ࢖͑ΔDjangoͷڭՊॻʯΛࢀߟʹ͍͖ͤͯͨͩ͞·ͨ͠
  23. Django 63- σΟεύο νϟʔ 63-DPOG Ϗϡʔ ϑΥʔϜ ςϯϓϨʔτ Ϟσϧ DjangoϓϩδΣΫτ

    ϒϥ΢β Webαʔό ΞϓϦέʔγϣϯαʔό ϦΫΤ ετ ֎෦Ϧιʔε ϛυϧ ΢ΣΞ Ϩεϙ ϯε ඇಉظରԠ ΫϥεϕʔεϏϡʔ 03.ΠϯλʔϑΣʔε
  24. Django 63- σΟεύο νϟʔ 63-DPOG Ϗϡʔ ϑΥʔϜ ςϯϓϨʔτ Ϟσϧ DjangoϓϩδΣΫτ

    ϒϥ΢β Webαʔό ΞϓϦέʔγϣϯαʔό ϦΫΤ ετ ֎෦Ϧιʔε ϛυϧ ΢ΣΞ Ϩεϙ ϯε ඇಉظରԠ ΫϥεϕʔεϏϡʔ 03.ΠϯλʔϑΣʔε
  25. Django 63- σΟεύο νϟʔ 63-DPOG Ϗϡʔ ϑΥʔϜ ςϯϓϨʔτ Ϟσϧ DjangoϓϩδΣΫτ

    ϒϥ΢β Webαʔό ΞϓϦέʔγϣϯαʔό ϦΫΤ ετ ֎෦Ϧιʔε ϛυϧ ΢ΣΞ Ϩεϙ ϯε ඇಉظରԠ ΫϥεϕʔεϏϡʔ 03.ΠϯλʔϑΣʔε
  26. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py
  27. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View async def post(self, request, *args, **kwargs): ... async def put(self, request, *args, **kwargs): ... class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py
  28. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View async def post(self, request, *args, **kwargs): ... class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py async def put(self, request, *args, **kwargs): ... ఆٛ࣌ͷ஫ҙ఺
  29. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View async def post(self, request, *args, **kwargs): ... class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py async def put(self, request, *args, **kwargs): ... ఆٛ࣌ͷ஫ҙ఺
  30. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View def post(self, request, *args, **kwargs): ... class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py async def put(self, request, *args, **kwargs): ... ఆٛ࣌ͷ஫ҙ఺
  31. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View def post(self, request, *args, **kwargs): ... class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py async def put(self, request, *args, **kwargs): ... ఆٛ࣌ͷ஫ҙ఺ *NQSPQFSMZ$PO fi HVSFE
  32. ΫϥεϕʔεϏϡʔͷඇಉظରԠ import asyncio from django.http import HttpResponse from django.views import

    View async def post(self, request, *args, **kwargs): ... class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform view logic using await. await asyncio.sleep(1) return HttpResponse("Hello async world!") views.py async def put(self, request, *args, **kwargs): ... ఆٛ࣌ͷ஫ҙ఺
  33. Django/views/generics/base.py class View: ⾮同期対応 @classproperty def view_is_async(cls): handlers = [

    getattr(cls, method) for method in cls.http_method_names if (method != "options" and hasattr(cls, method)) ] if not handlers: return False is_async = asyncio.iscoroutinefunction(handlers[0]) if not all(asyncio.iscoroutinefunction(h) == is_async for h in handlers[1:]): raise ImproperlyConfigured( f"{cls.__qualname__} HTTP handlers must either be all sync or all " "async." ) return is_async
  34. ΫϥεϕʔεϏϡʔಉظίʔυ class PokeView(View): URL = "https://pokeapi.co/api/v2/pokemon/" def get(self, request, *args,

    **kwargs): start = time() pokemons = [] for number in range(1, 152): url = f'https://pokeapi.co/api/v2/pokemon/{number}' r = requests.get(url) pokemon = r.json() pokemons.append({"name" : pokemon['name']}) finish = (time() - start) context = {"pokemons": pokemons, "finish_time": finish} return render(request, “sync.html", context) views.py ֎෦APIΛ࣮ߦ
  35. ΫϥεϕʔεϏϡʔඇಉظίʔυ class AsyncPokeView(View): URL = "https://pokeapi.co/api/v2/pokemon/" async def get(self, request,

    *args, **kwargs): start = time() async with httpx.AsyncClient() as client: tasks = [self.access_url_poke(client, number) for number in range(1, 152)] pokemmons = await asyncio.gather(*tasks, return_exceptions=True) finish = (time() - start) context = {"pokemons": pokemmons, "finish_time": finish} return render(request, "async.html", context) async def access_url_poke(self, client, num: int) -> str: r = await client.get(f"{self.URL}{num}") pokemon = r.json() return {"name": pokemon['name']} views.py ֎෦APIΛ࣮ߦ
  36. 同期 ⾮同期 •࣮ߦ݁Ռ •ಉظɿ18ඵ •ඇಉظɿ0.7ඵ •ඇಉظͱͯ΋͸΍͍ •APIΛ151ճ΋ୟ͘ඇಉظʹ༗རͳܭଌʢͻ͍͖ •ͦͷଞͷ࢖͍ํ - DjangoCon

    2022 •Async Django: The practical guide you've been *awaiting* for by Carlton Gibson •https://www.youtube.com/watch?v=B5uQPwX4VLo •֎෦APIΛಉ࣌ʹ࣮ߦ͢Δ৔߹ʹ࠾༻͠ͳ͍ख͸ͳ͍ •ʮඇಉظDjangoͷ͋ͳ͕ͨ଴ͪ๬ΜͰ͍࣮ͨ༻తͳΨΠυϒοΫʯνϟοτ Channels
  37. ⾮同期 ORM •QuerySetͷϝιουʹ઀಄ࣙʮaʯ͕͍ͭͨඇಉظ൛͕௥Ճ •໋໊نଇ͸3ͭͷީิ 1."_async" pre fi x, 2."_async" suf

    fi x 3."a" pre fi x _async_get get_async aget ଞʹ΋a.getͳͲ •ٞ࿦ͷ຤ɺPythonͷํ޲ੑ(e.g. __aiter__, __anext__, __aenter__, __aexit__ etc.) •3͕࠾༻ʹ IUUQTGPSVNEKBOHPQSPKFDUDPNUOBNJOHPGBTZODWBSJBOUT
  38. ⾮同期 ORM •QuerySetͷϝιουʹ઀಄ࣙʮaʯ͕͍ͭͨඇಉظ൛͕௥Ճ •db.models.guery •aiterator, aaggregate, acount, aget, acreate, abulk_create,

    abulk_update, • aget_or_create, aupdate_or_create, aearliest, alatest, a fi rst, alast, ain_bulk, • aupdate, adelete, aexists, acontains, aexplain •ʢ´-`ʣ.ŇoOʢ໊લ͕ؾʹͳΔ΋ͷ΋͋Δ… acount, aggregate, adelete …ʣ •·ͣ͸؆୯ʹಈ͔ͯ͠Έ·͠ΐ͏
  39. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ
  40. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ In [1]: from django.contrib.auth.models import User
  41. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ In [1]: from django.contrib.auth.models import User In [2]: admin_user = User.objects.get(id=1) In [3]: admin_user Out[3]: <User: admin>
  42. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ In [1]: from django.contrib.auth.models import User In [2]: admin_user = User.objects.get(id=1) In [3]: admin_user Out[3]: <User: admin> In [4]: admin_user = User.objects.aget(id=1)
  43. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ In [1]: from django.contrib.auth.models import User In [2]: admin_user = User.objects.get(id=1) In [3]: admin_user Out[3]: <User: admin> In [4]: admin_user = User.objects.aget(id=1) In [5]: admin_user Out[5]: <coroutine object QuerySet.aget at 0x107b36110>
  44. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ In [1]: from django.contrib.auth.models import User In [2]: admin_user = User.objects.get(id=1) In [3]: admin_user Out[3]: <User: admin> In [4]: admin_user = User.objects.aget(id=1) In [6]: admin_user = await User.objects.aget(id=1) In [5]: admin_user Out[5]: <coroutine object QuerySet.aget at 0x107b36110>
  45. ΫϥεϕʔεϏϡʔඇಉظίʔυ $ python manage.py shell Python 3.11.0 (v3.11.0:deaf509e8f, Oct 24

    2022, 14:43:23) [Clang 13.0.0 (clang-1300.0.29.30)] Type 'copyright', 'credits' or 'license' for more information IPython 8.6.0 -- An enhanced Interactive Python. Type '?' for help. views.py ֎෦APIΛ࣮ߦ In [1]: from django.contrib.auth.models import User In [2]: admin_user = User.objects.get(id=1) In [3]: admin_user Out[3]: <User: admin> In [4]: admin_user = User.objects.aget(id=1) In [6]: admin_user = await User.objects.aget(id=1) In [7]: admin_user Out[7]: <User: admin> In [5]: admin_user Out[5]: <coroutine object QuerySet.aget at 0x107b36110>
  46. ΫϥεϕʔεϏϡʔಉظίʔυ class SyncOrmView(View): def get(self, request, *args, **kwargs): start =

    time() users = [] for _ in range(100_000): users.append(User(name="Taro")) snippets = [] for _ in range(100_000): snippets.append(Snippet(title="PingPong")) User.objects.bulk_create(users) Snippet.objects.bulk_create(snippets) finish = (time() - start) context = {"finish_time": finish} return render(request, "sync.html", context) views.py ORM
  47. ΫϥεϕʔεϏϡʔಉظίʔυ class AsyncOrmView(View): async def post(self, request, *args, **kwargs): start

    = time() users = [] for _ in range(100_000): users.append(User(name="Taro")) snippets = [] for _ in range(100_000): snippets.append(Snippet(title="PingPong")) await asyncio.gather( self.check("user", User, users), self.check("snippet", Snippet, snippets) ) finish = (time() - start) context = {"finish_time": finish} return render(request, "async.html", context) async def check(self, name, model, data): print(f"start {name}") await model.objects.abulk_create(data) print(f"end {name}") views.py ORM
  48. abulk_create async def abulk_create( self, objs, batch_size=None, ignore_conflicts=False, update_conflicts=False, update_fields=None,

    unique_fields=None, ): return await sync_to_async(self.bulk_create)( objs=objs, batch_size=batch_size, ignore_conflicts=ignore_conflicts, update_conflicts=update_conflicts, update_fields=update_fields, unique_fields=unique_fields, )
  49. abulk_create async def abulk_create( self, objs, batch_size=None, ignore_conflicts=False, update_conflicts=False, update_fields=None,

    unique_fields=None, ): return await sync_to_async(self.bulk_create)( objs=objs, batch_size=batch_size, ignore_conflicts=ignore_conflicts, update_conflicts=update_conflicts, update_fields=update_fields, unique_fields=unique_fields, )
  50. sync_to_async •ίʔϧόοΫʹࢦఆ͞Εͨಉظؔ਺ʢ͜ͷ৔߹getʣΛඇಉظͬΆ࣮͘ߦͯ͠ฦ͢ def sync_to_async( func=None, thread_sensitive=True, executor=None, ): if func

    is None: return lambda f: SyncToAsync( f, thread_sensitive=thread_sensitive, executor=executor, ) return SyncToAsync( func, thread_sensitive=thread_sensitive, executor=executor, ) BTHJSFGTZODQZ
  51. SyncToAsync •ThreadPoolExecutorΛར༻͠ɺಉظؔ਺ΛΠϕϯτϧʔϓ಺Ͱ࣮ߦ͢Δ class SyncToAsync: ... async def __call__(self, *args, **kwargs):

    loop = asyncio.get_running_loop() ... executor = AsyncToSync.loop_thread_executors[loop] future = loop.run_in_executor( executor, functools.partial( self.thread_handler, loop, self.get_current_task(), sys.exc_info(), func, *args, **kwargs, ),
  52. SyncToAsync •ThreadPoolExecutorΛར༻͠ɺಉظؔ਺ΛΠϕϯτϧʔϓ಺Ͱ࣮ߦ͢Δ class SyncToAsync: ... async def __call__(self, *args, **kwargs):

    loop = asyncio.get_running_loop() ... executor = AsyncToSync.loop_thread_executors[loop] future = loop.run_in_executor( executor, functools.partial( self.thread_handler, loop, self.get_current_task(), sys.exc_info(), func, *args, **kwargs, ), Πϕϯτϧʔϓ಺Ͱ&YFDVUPSΛ࢖͏
  53. DEP 0009: Async-capable Django •ʢDEP͸DjangoͷPEPʣ •Sequencing ͱͯ͠3ஈ֊ •First round (hopefully

    in 3.0) •Further individual projects •Second round (hopefully in 3.1) IUUQTHJUIVCDPNEKBOHPEFQTCMPCNBJOBDDFQUFEBTZODSTU
  54. DEP 0009: Async-capable Django •ʢDEP͸DjangoͷPEPʣ •Sequencing ͱͯ͠3ஈ֊ •First round (hopefully

    in 3.0) •Further individual projects •Second round (hopefully in 3.1) •ORM (async-wrapper interface around existing sync core) •طଘͷಉظίΞʹରԠͨ͠ඇಉظϥούʔΠϯλϑΣʔε •ORM (native async with sync wrappers for backwards compatibility) ޙํޓ׵ੑͷͨΊͷಉظϥούʔΛඋ͑ͨωΠςΟϒඇಉظ IUUQTHJUIVCDPNEKBOHPEFQTCMPCNBJOBDDFQUFEBTZODSTU
  55. DEP 0009: Async-capable Django •ʢDEP͸DjangoͷPEPʣ •Sequencing ͱͯ͠3ஈ֊ •First round (hopefully

    in 3.0) •Further individual projects •Second round (hopefully in 3.1) •ORM (async-wrapper interface around existing sync core) •طଘͷಉظίΞʹରԠͨ͠ඇಉظϥούʔΠϯλϑΣʔε •ORM (native async with sync wrappers for backwards compatibility) ޙํޓ׵ੑͷͨΊͷಉظϥούʔΛඋ͑ͨωΠςΟϒඇಉظ IUUQTHJUIVCDPNEKBOHPEFQTCMPCNBJOBDDFQUFEBTZODSTU ࣮૷ॱং͸༧ఆͲ͓Γʂ
  56. 4.1 ORM 🤔 •Θͨ͠ͷߟ͑Δཧ༝͸3ͭ •ޓ׵ੑ •ޓ׵ੑΛҡ࣋͢Δํ๏Ͱ࣮૷ΛਐΊ͍ͯΔ •ʢ૝૾ʣࢿۚ΋Өڹ͕͋Δͷ͔ʁ •IF͔ΒରԠ͢Δͷ͸౰ॳͷ༧ఆͲ͓Γ •ඇಉظରԠͷϝΠϯ։ൃऀͷϦιʔεෆ଍ 🤔

    •DEP 9 / asgiref ͷ Andrew Godwin ࢯ •PyConJP 2022ͷΩʔϊʔτͷ࿩ʢFaster C Pythonʣ💰 •DEP͸ͦΕ΄Ͳ֬ݻͨΔ࢓༷Ͱ͸ͳͦ͞͏ʢ໋໊نଇ΋มߋʹͳͬͯΔ •DEP 9 Ͱ͸ࢿۚௐୡͷ࿩΋ग़͍ͯΔ Donationͷϖʔδ΋
  57. 謝辞 •Asynchronous ORM •https://forum.djangoproject.com/t/asynchronous-orm/5925/21 •ݱ৔Ͱ࢖͑Δ Django ͷڭՊॻ - ԣ੉ ໌ਔ(ஶ)

    •https://akiyoko.booth.pm/items/1059917 •࣮ફDjango PythonʹΑΔຊ֨WebΞϓϦέʔγϣϯ։ൃ - ࣳా ক (ஶ) •https://www.shoeisha.co.jp/book/detail/9784798153964 • Async Django: The practical guide you've been *awaiting* for by Carlton Gibson - DjangoCon Europe 2022 •https://www.youtube.com/watch?v=Lfe2zsGS0Js • Keynote: State of the Object-Relational Mapping (ORM) - Simon Charette •https://2022.djangocon.us/talks/keynote-state-of-orm/