$30 off During Our Annual Pro Sale. View Details »

Django 4.1のAsynchronous

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/

Junya Fukuda

November 12, 2022
Tweet

More Decks by Junya Fukuda

Other Decks in Technology

Transcript

  1. Django 4.1 での Asynchronous
    Junya Fukuda
    DjangoCongress JP 2022

    View Slide

  2. •෱ా ൏໵ʢJunya Fukudaʣʢ@JunyaFffʣ


    •גࣜձࣾ೔ຊγεςϜٕݚʢJSLʣॴଐ ௕໺ݝͷձࣾ


    •WebΤϯδχΞ


    •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ


    •ʢ͓͠͝ͱͰʣόϦϡʔϒοΫε


    •ຊ޷͖ʹѪ͞ΕΔαʔϏεΛ໨ࢦͯ͠ʢݹຊങऔɾൢചʣ
    •GEEKLAB.NAGANO - ίϛϡχςΟεϖʔεӡӦ

    View Slide

  3. Python実践
    •2022೥1݄ൃച ٕज़ධ࿦ࣾ


    •Python 3 ΤϯδχΞೝఆ࣮ફࢼݧ ओڭࡐ


    •2࡭໨ʹ͓͢͢Ίʂࣙॻతʹ࢖͍ͬͯ͋͛ͯͩ͘͞ʂ
    • ҎԼͷষΛ୲౰͍ͯ͠·͢


    • Chapter2 ίʔσΟϯάن໿


    • Chapter5 ܕώϯτ


    • Chapter19 ฒߦॲཧɼฒྻॲཧ

    View Slide

  4. Django 4.1 での ⾮同期

    View Slide

  5. Pythonで⾮同期、使っていますか?✋

    View Slide

  6. ありがとうございます。

    View Slide

  7. ですよね。
    なぜ使わないのでしょうか?

    View Slide

  8. ⾮同期 使 理由 考
    •׳ΕͯΔಉظॲཧͰे෼
    •IO͕ͳ͍ʢػցֶश΍σʔλ෼ੳ͕த৺ʣʢCPUʹ͕Μ͹ΒͤΔ͜ͱଟ͍ʣ
    •ඇಉظॲཧͬͯɺ༧ଌͰ͖ͳ͍ಈ͖Λͦ͠͏
    •ଞͷݴޠͰॻ͍ͪΌ͏ʢGo΍JS(nodejs/deno..),Rust,C#,SwiftͳͲʣ

    View Slide

  9. View Slide

  10. Djangoの⾮同期対応を待ってるのです

    View Slide

  11. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT

    View Slide

  12. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT

    View Slide

  13. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT

    View Slide

  14. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT
    Note that, at this stage, the underlying database operations remain synchronous

    View Slide

  15. Django 4.1 Asynchronous
    ͜ͷஈ֊Ͱ͸ɺجຊతͳσʔλϕʔεૢ࡞͸ಉظͷ··Ͱ͋Δ͜ͱʹ஫ҙ͍ͯͩ͘͠͞ɻ
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT
    Note that, at this stage, the underlying database operations remain synchronous

    View Slide

  16. 🤔

    View Slide

  17. 🤔
    ͳͥɺ03.͸ΠϯλʔϑΣʔε͚ͩରԠͨ͠ΜͩΖ͏
    ͍·ɺ%KBOHPͷඇಉظରԠ࣮ͬͯࡍͲ͏ͳ͍ͬͯΔΜͩΖ͏ʜ

    View Slide

  18. ( 話 ?)
    •ڈ೥ͷDjangoCongress JP 2021 ͰͷτʔΫΛΞοϓσʔτ͍ͨ͠
    •Django 3.2 ASGI ରԠ - ͜Θ͘ͳ͍ asyncio جૅͱ async view ͷ࢖͍ॴ
    IUUQTMPHNJKQUFDIBSUJDMFT
    •DjangoͷORM͸ͳͥਖ਼ࣜରԠͰ͸ͳ͍ͷ͔
    •΋͔ͨ͠͠Βͦ͏ࢥΘΕͨํ΋͍Βͬ͠ΌΔ͔΋͠Ε·ͤΜʢΘͨ͠

    View Slide

  19. 本⽇
    •Django 4.1 ඇಉظରԠ͕Θ͔ͬͨ
    •ΫϥεϕʔεϏϡʔ
    •ORMͷΠϯλʔϑΣʔε
    •Ωʔϫʔυ͸
    •·ͨඇಉظORMΠϯλʔϑΣʔε͸ͳͥ׬શରԠͰ͸ͳ͘ɺಉظͷ··ͳͷ͔
    ޓ׵ੑ

    View Slide

  20. 話 ・話
    •DjangoͷViewͷجຊతͳ࢓૊Έ


    •Djangoͷmodelͷఆٛ


    •asyncioͷࡉ͔͍͜ͱ
    •࿩͞ͳ͍͜ͱ
    •࿩͢͜ͱ
    •Django 4.1ͷΫϥεϕʔεϏϡʔɾORM

    View Slide

  21. •Django 4.1 ඇಉظରԠͱ͍··Ͱͷ͓͞Β͍


    •ΫϥεϕʔεϏϡʔͷඇಉظରԠ


    •؆୯ͳίʔυ ΫϥεϕʔεϏϡʔͷ಺ଆ


    •ಉظɾඇಉظΫϥεϕʔεϏϡʔͰͷಈ࡞ൺֱ


    •ඇಉظ ORM ΠϯλʔϑΣʔε


    •֓ཁ


    •ಉظɾඇಉظORMͰͷಈ࡞ൺֱ


    •ඇಉظORM ΠϯλʔϑΣʔεͷ޲͜͏ଆ

    View Slide

  22. •Django 4.1 ඇಉظରԠͱ͍··Ͱͷ͓͞Β͍


    •ΫϥεϕʔεϏϡʔͷඇಉظରԠ


    •؆୯ͳίʔυ ΫϥεϕʔεϏϡʔͷ಺ଆ


    •ಉظɾඇಉظΫϥεϕʔεϏϡʔͰͷಈ࡞ൺֱ


    •ඇಉظ ORM ΠϯλʔϑΣʔε


    •֓ཁ


    •ಉظɾඇಉظORMͰͷಈ࡞ൺֱ


    •ඇಉظORM ΠϯλʔϑΣʔεͷ޲͜͏ଆ

    View Slide

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

    View Slide

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

    View Slide

  25. - Django ⾮同期対応
    2005
    Django


    OSS
    •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  26. - Django ⾮同期対応
    2005
    Django


    OSS
    1.0
    2008
    •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  27. - Django ⾮同期対応
    2005
    Django


    OSS
    1.0 1.4 LTS
    2012
    2008
    •Έͳ͞Μ͕ॳΊͯ͞ΘͬͨDjangoͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  28. - Django ⾮同期対応
    2005
    Django


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

    View Slide

  29. - Django ⾮同期対応
    2005
    Django


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

    View Slide

  30. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  31. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  32. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  33. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  34. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  35. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  36. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  37. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  38. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  39. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  40. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  41. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  42. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  43. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  44. - 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ͷόʔδϣϯ͸͍ͭ͘Ͱ͠ΐ͏͔ʁ

    View Slide

  45. - asyncio 基本
    •ඇಉظॲཧͷίʔυΛॻͨ͘ΊͷެࣜϥΠϒϥϦ
    •ෳ਺ͷλεΫΛಉ࣌ʹॲཧ͢Δ
    •I/Oό΢ϯυͳॲཧʢDBΞΫηε/HTTPϦΫΤετͳͲʣͰޮՌΛൃش
    •֎෦API-A, ֎෦API-B, ֎෦API-C Λಉ࣌ʹ࣮ߦ͍ͨ͠
    •ಉظॲཧͩͱ ॱ൪ʹ࣮ߦ
    " # $

    View Slide

  46. - asyncio 基本
    •ඇಉظॲཧͷίʔυΛॻͨ͘ΊͷެࣜϥΠϒϥϦ
    •ෳ਺ͷλεΫΛಉ࣌ʹॲཧ͢Δ
    •I/Oό΢ϯυͳॲཧʢDBΞΫηε/HTTPϦΫΤετͳͲʣͰޮՌΛൃش
    •֎෦API-A, ֎෦API-B, ֎෦API-C Λಉ࣌ʹ࣮ߦ͍ͨ͠
    •ඇಉظॲཧͩͱ ·ͱΊͯಉ࣌ʹ࣮ߦ
    C
    B
    A

    View Slide

  47. - asyncio 基本
    •ඇಉظॲཧͷίʔυΛॻͨ͘Ίͷඪ४ϥΠϒϥϦ
    •ຖόʔδϣϯਐԽ ߴϨϕϧAPI͕ॆ࣮ - ͱͯ΋ॻ͖΍͍͢
    •ෳ਺ͷλεΫΛಉ࣌ʹॲཧ͢Δ
    •I/Oό΢ϯυͳॲཧʢDBΞΫηε/HTTPϦΫΤετͳͲʣͰޮՌΛൃش
    •async/await ߏจ


    •λεΫΛొ࿥͢Δasyncio.create_task() - ʮλεΫʯ = ॲཧͩͱࢥ͍ͬͯͩ͘͞ɻ


    •ॲཧΛฒߦʹ͢Δasyncio.gather()


    •ྫ֎΍ΩϟϯηϧΛॊೈʹ asyncio.TaskGroup
    •αʔυύʔςΟͷϥΠϒϥϦΛ࢖͏৔߹ɺඇಉظରԠ͍ͯ͠Δඞཁ͕͋Δ

    View Slide

  48. Django

    View Slide

  49. Django
    63-
    σΟεύο
    νϟʔ
    63-DPOG
    Ϗϡʔ
    ϑΥʔϜ
    ςϯϓϨʔτ
    Ϟσϧ
    DjangoϓϩδΣΫτ
    ϒϥ΢β
    Webαʔό


    ΞϓϦέʔγϣϯαʔό
    ϦΫΤ
    ετ
    ֎෦Ϧιʔε
    ϛυϧ
    ΢ΣΞ
    Ϩεϙ
    ϯε

    View Slide

  50. Django
    63-
    σΟεύο
    νϟʔ
    63-DPOG
    Ϗϡʔ
    ϑΥʔϜ
    ςϯϓϨʔτ
    Ϟσϧ
    DjangoϓϩδΣΫτ
    ϒϥ΢β
    Webαʔό


    ΞϓϦέʔγϣϯαʔό
    ϦΫΤ
    ετ
    ֎෦Ϧιʔε
    ϛυϧ
    ΢ΣΞ
    Ϩεϙ
    ϯε
    ʮݱ৔Ͱ࢖͑ΔDjangoͷڭՊॻʯΛࢀߟʹ͍͖ͤͯͨͩ͞·ͨ͠

    View Slide

  51. Django
    63-
    σΟεύο
    νϟʔ
    63-DPOG
    Ϗϡʔ
    ϑΥʔϜ
    ςϯϓϨʔτ
    Ϟσϧ
    DjangoϓϩδΣΫτ
    ϒϥ΢β
    Webαʔό


    ΞϓϦέʔγϣϯαʔό
    ϦΫΤ
    ετ
    ֎෦Ϧιʔε
    ϛυϧ
    ΢ΣΞ
    Ϩεϙ
    ϯε
    ඇಉظରԠ
    ΫϥεϕʔεϏϡʔ
    03.ΠϯλʔϑΣʔε

    View Slide

  52. Django
    63-
    σΟεύο
    νϟʔ
    63-DPOG
    Ϗϡʔ
    ϑΥʔϜ
    ςϯϓϨʔτ
    Ϟσϧ
    DjangoϓϩδΣΫτ
    ϒϥ΢β
    Webαʔό


    ΞϓϦέʔγϣϯαʔό
    ϦΫΤ
    ετ
    ֎෦Ϧιʔε
    ϛυϧ
    ΢ΣΞ
    Ϩεϙ
    ϯε
    ඇಉظରԠ
    ΫϥεϕʔεϏϡʔ
    03.ΠϯλʔϑΣʔε

    View Slide

  53. Django
    63-
    σΟεύο
    νϟʔ
    63-DPOG
    Ϗϡʔ
    ϑΥʔϜ
    ςϯϓϨʔτ
    Ϟσϧ
    DjangoϓϩδΣΫτ
    ϒϥ΢β
    Webαʔό


    ΞϓϦέʔγϣϯαʔό
    ϦΫΤ
    ετ
    ֎෦Ϧιʔε
    ϛυϧ
    ΢ΣΞ
    Ϩεϙ
    ϯε
    ඇಉظରԠ
    ΫϥεϕʔεϏϡʔ
    03.ΠϯλʔϑΣʔε

    View Slide

  54. •Django 4.1 ඇಉظରԠͱ͍··Ͱͷ͓͞Β͍


    •ΫϥεϕʔεϏϡʔͷඇಉظରԠ


    •؆୯ͳίʔυ ΫϥεϕʔεϏϡʔͷ಺ଆ


    •ಉظɾඇಉظΫϥεϕʔεϏϡʔͰͷಈ࡞ൺֱ


    •ඇಉظ ORM ΠϯλʔϑΣʔε


    •֓ཁ


    •ಉظɾඇಉظORMͰͷಈ࡞ൺֱ


    •ඇಉظORM ΠϯλʔϑΣʔεͷ޲͜͏ଆ

    View Slide

  55. ⾮同期対応
    •viewΫϥεͰίϧʔνϯͷఆ͕ٛՄೳ
    •django.views.generic.base.view ͢΂ͯͷviewͷ਌Ϋϥε
    •get, post, put, delete, ͳͲͷϦΫΤετϝιου͕ରԠ
    •؆୯ͳίʔυΛݟͯΈ·͠ΐ͏

    View Slide

  56. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    import asyncio


    from django.http import HttpResponse


    from django.views import View
    views.py

    View Slide

  57. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    import asyncio


    from django.http import HttpResponse


    from django.views import View
    views.py

    View Slide

  58. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    import asyncio


    from django.http import HttpResponse


    from django.views import View
    class AsyncView(View):
    views.py

    View Slide

  59. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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

    View Slide

  60. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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

    View Slide

  61. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    urlpatterns = [


    ]
    urls.py

    View Slide

  62. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    urlpatterns = [


    ]
    urls.py
    path('sample/', AsyncView.as_view(), name='sample'),

    View Slide

  63. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    urlpatterns = [


    ]
    urls.py
    path('sample/', AsyncView.as_view(), name='sample'),

    View Slide

  64. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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):


    ...
    ఆٛ࣌ͷ஫ҙ఺

    View Slide

  65. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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):


    ...
    ఆٛ࣌ͷ஫ҙ఺

    View Slide

  66. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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):


    ...
    ఆٛ࣌ͷ஫ҙ఺

    View Slide

  67. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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

    View Slide

  68. ΫϥεϕʔεϏϡʔͷඇಉظରԠ
    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):


    ...
    ఆٛ࣌ͷ஫ҙ఺

    View Slide

  69. ⾮同期対応
    •ίϛοτ͸1ͭ

    View Slide

  70. ⾮同期対応
    •ίϛοτ͸1ͭ
    •मਖ਼͸ܰඍ υΩϡϝϯτɾςετΛআ͘ͱ30ߦఔ౓
    IUUQTHJUIVCDPNEKBOHPEKBOHPQVMM

    View Slide

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


    View Slide

  72. Django/views/generics/base.py
    class View:
    ⾮同期対応
    ...


    if cls.view_is_async:


    view._is_coroutine = asyncio.coroutines._is_coroutine


    View Slide

  73. Django/views/generics/base.py
    class View:
    ⾮同期対応
    ...


    if self.view_is_async:


    async def func():


    return response


    return func()


    else:


    return response


    View Slide

  74. ⾮同期対応
    •ίϛοτ͸1ͭ
    •मਖ਼͸ܰඍ υΩϡϝϯτɾςετΛআ͘ͱ30ߦఔ౓
    IUUQTHJUIVCDPNEKBOHPEKBOHPQVMM
    •asgi.pyͳͲΛؚΊରԠͷ४උ͸੔͍ͬͯͨ

    View Slide

  75. 同期 ⾮同期
    •ΫϥεϕʔεϏϡʔͰ֎෦APIΛ࣮ߦ͢Δྫ
    •ಉظɾඇಉظͰͦΕͧΕ ׬ྃ·Ͱͷ࣌ؒΛܭଌ
    •pokemonͷඇެࣜAPIʢओʹֶश޲͚ͷAPI ɺ༻๏༰ྔ͸कͬͯ
    •viewΫϥεΛར༻͠ɺςϯϓϨʔτͰදࣔ͢Δ
    •151ඖͷϙέϞϯͷ໊લΛऔಘ

    View Slide

  76. 同期 ⾮同期
    •ಈ࡞؀ڥ - ϩʔΧϧ
    •MacBook Proʢ14Πϯνɺ2021ʣ
    •Apple M1 Pro ϝϞϦ32gb

    View Slide

  77. 同期処理
    ⾮同期処理

    View Slide

  78. 同期処理
    ⾮同期処理
    requests

    View Slide

  79. ΫϥεϕʔεϏϡʔಉظίʔυ
    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Λ࣮ߦ

    View Slide

  80. urlpatterns = [


    path('sync/', PokeView.as_view(), name=‘syncpoke'),


    ]
    ΫϥεϕʔεϏϡʔಉظίʔυ urls.py
    ֎෦APIΛ࣮ߦ

    View Slide

  81. ΫϥεϕʔεϏϡʔͷ ಉظίʔυ urls.py

    View Slide

  82. ΫϥεϕʔεϏϡʔͷ ಉظίʔυ urls.py

    View Slide

  83. ΫϥεϕʔεϏϡʔͷ ಉظίʔυ urls.py

    View Slide

  84. 同期処理
    ⾮同期処理

    View Slide

  85. 同期処理
    ⾮同期処理
    httpx

    View Slide

  86. 同期処理
    ⾮同期処理
    httpx
    async対応のサードパーティライブラリ

    View Slide

  87. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    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Λ࣮ߦ

    View Slide

  88. urlpatterns = [


    path('async/', AsyncPokeView.as_view(), name=‘asyncpoke'),


    ]
    ΫϥεϕʔεϏϡʔඇಉظίʔυ urls.py
    ֎෦APIΛ࣮ߦ

    View Slide

  89. ΫϥεϕʔεϏϡʔඇಉظίʔυ ࣮ߦ݁Ռ
    ֎෦APIΛ࣮ߦ

    View Slide

  90. ΫϥεϕʔεϏϡʔඇಉظίʔυ ࣮ߦ݁Ռ
    ֎෦APIΛ࣮ߦ

    View Slide

  91. ΫϥεϕʔεϏϡʔඇಉظίʔυ ࣮ߦ݁Ռ
    ֎෦APIΛ࣮ߦ

    View Slide

  92. 同期 ⾮同期
    •࣮ߦ݁Ռ
    •ಉظɿ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

    View Slide

  93. •Django 4.1 ඇಉظରԠͱ͍··Ͱͷ͓͞Β͍


    •ΫϥεϕʔεϏϡʔͷඇಉظରԠ


    •؆୯ͳίʔυ ΫϥεϕʔεϏϡʔͷ಺ଆ


    •ಉظɾඇಉظΫϥεϕʔεϏϡʔͰͷಈ࡞ൺֱ


    •ඇಉظ ORM ΠϯλʔϑΣʔε


    •֓ཁ


    •ಉظɾඇಉظORMͰͷಈ࡞ൺֱ


    •ඇಉظORM ΠϯλʔϑΣʔεͷ޲͜͏ଆ

    View Slide

  94. ⾮同期 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

    View Slide

  95. ⾮同期 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 …ʣ
    •·ͣ͸؆୯ʹಈ͔ͯ͠Έ·͠ΐ͏

    View Slide

  96. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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Λ࣮ߦ

    View Slide

  97. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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

    View Slide

  98. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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]:

    View Slide

  99. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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]:
    In [4]: admin_user = User.objects.aget(id=1)

    View Slide

  100. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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]:
    In [4]: admin_user = User.objects.aget(id=1)
    In [5]: admin_user


    Out[5]:

    View Slide

  101. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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]:
    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]:

    View Slide

  102. ΫϥεϕʔεϏϡʔඇಉظίʔυ
    $ 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]:
    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]:
    In [5]: admin_user


    Out[5]:

    View Slide

  103. 動作 ⽐較 - ORM
    •̎छྨͷϞσϧ ͦΕͧΕ100,000݅ొ࿥͢Δ
    •ಉظɾඇಉظͰͦΕͧΕ
    •bulk_create/abulk_create Λ࣮ߦ
    •଎౓ͱ࣮ߦͷྲྀΕΛݟͯΈΔ

    View Slide

  104. 動作 ⽐較 - ORM
    •ಈ࡞؀ڥ - ϩʔΧϧ
    •MacBook Proʢ14Πϯνɺ2021ʣ
    •Apple M1 Pro ϝϞϦ32gb

    View Slide

  105. 同期処理
    ⾮同期処理

    View Slide

  106. ΫϥεϕʔεϏϡʔಉظίʔυ
    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

    View Slide

  107. urlpatterns = [


    path('sync/', SyncOrmView.as_view(), name=‘syncbulk'),


    ]
    urls.py
    ΫϥεϕʔεϏϡʔಉظίʔυ ORM

    View Slide

  108. ࣮ߦ݁Ռ
    ΫϥεϕʔεϏϡʔಉظίʔυ ORM

    View Slide

  109. 同期処理
    ⾮同期処理

    View Slide

  110. ΫϥεϕʔεϏϡʔಉظίʔυ
    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

    View Slide

  111. urlpatterns = [


    path('async/', AsyncOrmView.as_view(), name=‘asyncorm’),


    ]
    urls.py
    ΫϥεϕʔεϏϡʔಉظίʔυ ORM

    View Slide

  112. ࣮ߦ݁Ռ
    ΫϥεϕʔεϏϡʔಉظίʔυ ORM

    View Slide

  113. ࣮ߦ݁Ռ
    ΫϥεϕʔεϏϡʔಉظίʔυ ORM
    start user


    start snippets


    end user


    end snippets

    View Slide

  114. ࣮ߦ݁Ռ
    ΫϥεϕʔεϏϡʔಉظίʔυ ORM
    start user


    start snippets


    end user


    end snippets

    View Slide

  115. 同期 ⾮同期
    •ಈ࡞ͷൺֱ
    •ಈ࡞͔Βɺฒߦʹ࣮ߦ͞Ε͍ͯΔ
    •ಈ࡞ͷൺֱ݁Ռ͸มΘΒͳ͍
    •ͪΐͬͱORMͷཪଆͷ࣮૷ΛݟͯΈ·͠ΐ͏
    •ಉظɿ 2.6ඵ
    •ඇಉظɿ 2.6ඵ
    •౰વͷಈ࡞ - ΠϯλʔϑΣʔεͷΈͷରԠ
    •ͳͥ͜ͷΑ͏ͳಈ͖ʹͳ͍ͬͯΔͷ͔

    View Slide

  116. 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,


    )


    View Slide

  117. 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,


    )


    View Slide

  118. aget
    async def aget(self, *args, **kwargs):


    return await sync_to_async(self.get)(*args, **kwargs)

    View Slide

  119. aget
    async def aget(self, *args, **kwargs):


    return await sync_to_async(self.get)(*args, **kwargs)

    View Slide

  120. sync_to_async
    •ίʔϧόοΫʹࢦఆ͞Εͨಉظؔ਺ʢ͜ͷ৔߹getʣΛඇಉظͬΆ࣮͘ߦͯ͠ฦ͢
    async def aget(self, *args, **kwargs):


    return await sync_to_async(self.get)(*args, **kwargs)

    View Slide

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

    View Slide

  122. SyncToAsync
    •ThreadPoolExecutorΛར༻͠ɺಉظؔ਺ΛΠϕϯτϧʔϓ಺Ͱ࣮ߦ͢Δ
    class SyncToAsync:


    ...


    async def __call__(self, *args, **kwargs):


    loop = asyncio.get_running_loop()


    ...


    executor = AsyncToSync.loop_thread_executors[loop]




    View Slide

  123. 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,


    ),


    View Slide

  124. 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Λ࢖͏

    View Slide

  125. - ORM ⾮同期
    •Ͱ͸ͳͥasyncରԠΛORMΠϯλʔϑΣʔε͸ͨ͠ͷ͔

    View Slide

  126. - ORM ⾮同期
    •Ͱ͸ͳͥasyncରԠΛORMΠϯλʔϑΣʔε͸ͨ͠ͷ͔
    •։ൃऀ͸ҙࣝ͢Δ͜ͱͳ͘ɺasync/awaitͰॻ͘͜ͱ͕Ͱ͖Δ
    •ඇಉظ΁ͷҠߦʹࡍ͠ɺ͋Β͔͡Ίมߋ͓ͯ͘͜͠ͱ͕Ͱ͖Δ

    View Slide

  127. - ORM ⾮同期
    •Ͱ͸ͳͥasyncରԠΛORMΠϯλʔϑΣʔε͸ͨ͠ͷ͔
    •։ൃऀ͸ҙࣝ͢Δ͜ͱͳ͘ɺasync/awaitͰॻ͘͜ͱ͕Ͱ͖Δ
    •ඇಉظ΁ͷҠߦʹࡍ͠ɺ͋Β͔͡Ίมߋ͓ͯ͘͜͠ͱ͕Ͱ͖Δ
    •ORMͷͨΊʹɺViewΛඇಉظʹ͠ͳͯ͘΋Α͍


    •channels΍֎෦ϦιʔεΛར༻͢Δ৔߹


    •ORM͸ඇಉظIFΛར༻͠಺෦ಉظͰಈ࡞ͤ͞Δ

    View Slide

  128. - ORM ⾮同期
    •Ͱ͸ͳͥasyncରԠΛORMΠϯλʔϑΣʔε͸ͨ͠ͷ͔
    •։ൃऀ͸ҙࣝ͢Δ͜ͱͳ͘ɺasync/awaitͰॻ͘͜ͱ͕Ͱ͖Δ
    •ඇಉظ΁ͷҠߦʹࡍ͠ɺ͋Β͔͡Ίมߋ͓ͯ͘͜͠ͱ͕Ͱ͖Δ
    •ORMͷͨΊʹɺViewΛඇಉظʹ͠ͳͯ͘΋Α͍


    •channels΍֎෦ϦιʔεΛར༻͢Δ৔߹


    •ORM͸ඇಉظIFΛར༻͠಺෦ಉظͰಈ࡞ͤ͞Δ

    View Slide

  129. DEP 0009: Async-capable Django
    •ʢDEP͸DjangoͷPEPʣ
    •Sequencing ͱͯ͠3ஈ֊
    IUUQTHJUIVCDPNEKBOHPEFQTCMPCNBJOBDDFQUFEBTZODSTU

    View Slide

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

    View Slide

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

    View Slide

  132. 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
    ࣮૷ॱং͸༧ఆͲ͓Γʂ

    View Slide

  133. 4.1 ORM 🤔
    •Θͨ͠ͷߟ͑Δཧ༝͸3ͭ

    View Slide

  134. 4.1 ORM 🤔
    •Θͨ͠ͷߟ͑Δཧ༝͸3ͭ
    •ޓ׵ੑ
    •ޓ׵ੑΛҡ࣋͢Δํ๏Ͱ࣮૷ΛਐΊ͍ͯΔ
    •IF͔ΒରԠ͢Δͷ͸౰ॳͷ༧ఆͲ͓Γ
    •DEP͸ͦΕ΄Ͳ֬ݻͨΔ࢓༷Ͱ͸ͳͦ͞͏ʢ໋໊نଇ΋มߋʹͳͬͯΔ

    View Slide

  135. 4.1 ORM 🤔
    •Θͨ͠ͷߟ͑Δཧ༝͸3ͭ
    •ޓ׵ੑ
    •ޓ׵ੑΛҡ࣋͢Δํ๏Ͱ࣮૷ΛਐΊ͍ͯΔ
    •IF͔ΒରԠ͢Δͷ͸౰ॳͷ༧ఆͲ͓Γ
    •ඇಉظରԠͷϝΠϯ։ൃऀͷϦιʔεෆ଍
    •DEP͸ͦΕ΄Ͳ֬ݻͨΔ࢓༷Ͱ͸ͳͦ͞͏ʢ໋໊نଇ΋มߋʹͳͬͯΔ

    View Slide

  136. 4.1 ORM 🤔
    •Θͨ͠ͷߟ͑Δཧ༝͸3ͭ
    •ޓ׵ੑ
    •ޓ׵ੑΛҡ࣋͢Δํ๏Ͱ࣮૷ΛਐΊ͍ͯΔ
    •ʢ૝૾ʣࢿۚ΋Өڹ͕͋Δͷ͔ʁ
    •IF͔ΒରԠ͢Δͷ͸౰ॳͷ༧ఆͲ͓Γ
    •ඇಉظରԠͷϝΠϯ։ൃऀͷϦιʔεෆ଍
    •DEP 9 / asgiref ͷ Andrew Godwin ࢯ
    •DEP͸ͦΕ΄Ͳ֬ݻͨΔ࢓༷Ͱ͸ͳͦ͞͏ʢ໋໊نଇ΋มߋʹͳͬͯΔ

    View Slide

  137. 4.1 ORM 🤔
    •Θͨ͠ͷߟ͑Δཧ༝͸3ͭ
    •ޓ׵ੑ
    •ޓ׵ੑΛҡ࣋͢Δํ๏Ͱ࣮૷ΛਐΊ͍ͯΔ
    •ʢ૝૾ʣࢿۚ΋Өڹ͕͋Δͷ͔ʁ
    •IF͔ΒରԠ͢Δͷ͸౰ॳͷ༧ఆͲ͓Γ
    •ඇಉظରԠͷϝΠϯ։ൃऀͷϦιʔεෆ଍ 🤔
    •DEP 9 / asgiref ͷ Andrew Godwin ࢯ
    •PyConJP 2022ͷΩʔϊʔτͷ࿩ʢFaster C Pythonʣ💰
    •DEP͸ͦΕ΄Ͳ֬ݻͨΔ࢓༷Ͱ͸ͳͦ͞͏ʢ໋໊نଇ΋มߋʹͳͬͯΔ
    •DEP 9 Ͱ͸ࢿۚௐୡͷ࿩΋ग़͍ͯΔ Donationͷϖʔδ΋

    View Slide

  138. わたしたちにできること

    View Slide

  139. わたしたちにできること
    開発者の

    View Slide

  140. わたしたちにできること
    (経営者の⽅は… 🙏
    開発者の

    View Slide

  141. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT
    /PUFUIBU BUUIJTTUBHF UIFVOEFSMZJOHEBUBCBTFPQFSBUJPOTSFNBJOTZODISPOPVT
    ͜ͷஈ֊Ͱ͸ɺجຊతͳσʔλϕʔεૢ࡞͸ಉظͷ··Ͱ͋Δ͜ͱʹ஫ҙ͍ͯͩ͘͠͞ɻ

    View Slide

  142. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT
    /PUFUIBU BUUIJTTUBHF UIFVOEFSMZJOHEBUBCBTFPQFSBUJPOTSFNBJOTZODISPOPVT
    ͜ͷஈ֊Ͱ͸ɺجຊతͳσʔλϕʔεૢ࡞͸ಉظͷ··Ͱ͋Γɺ

    View Slide

  143. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT
    /PUFUIBU BUUIJTTUBHF UIFVOEFSMZJOHEBUBCBTFPQFSBUJPOTSFNBJOTZODISPOPVT
    XJUIDPOUSJCVUJPOTPOHPJOHUPQVTIBTZODISPOPVTTVQQPSU
    ͜ͷஈ֊Ͱ͸ɺجຊతͳσʔλϕʔεૢ࡞͸ಉظͷ··Ͱ͋Γɺ

    View Slide

  144. Django 4.1 Asynchronous
    IUUQTEPDTEKBOHPQSPKFDUDPNFOSFMFBTFT
    /PUFUIBU BUUIJTTUBHF UIFVOEFSMZJOHEBUBCBTFPQFSBUJPOTSFNBJOTZODISPOPVT
    XJUIDPOUSJCVUJPOTPOHPJOHUPQVTIBTZODISPOPVTTVQQPSU
    ͜ͷஈ֊Ͱ͸ɺجຊతͳσʔλϕʔεૢ࡞͸ಉظͷ··Ͱ͋Γɺ
    ඇಉظͷαϙʔτΛਪਐ͢ΔͨΊͷߩݙ͕ଓ͍͍ͯ·͢ɻ

    View Slide

  145. •Django͸OSS

    View Slide

  146. •Django͸OSS
    •ඇಉظORMରԠʹ޲͚ͯɺߩݙ͕ߦΘΕ͍ͯΔ

    View Slide

  147. •Django͸OSS
    •ඇಉظORMରԠʹ޲͚ͯɺߩݙ͕ߦΘΕ͍ͯΔ

    View Slide

  148. •Django͸OSS
    •ඇಉظORMରԠʹ޲͚ͯɺߩݙ͕ߦΘΕ͍ͯΔ

    View Slide

  149. •Django͸OSS
    •ඇಉظORMରԠʹ޲͚ͯɺߩݙ͕ߦΘΕ͍ͯΔ
    •IFͷΈͷରԠͰ͋Δࠓ͸ɺ೉қ౓΋ߴ͘ͳ͘ߩݙ͠΍͍͔͢΋

    View Slide

  150. 謝辞
    •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/

    View Slide

  151. ご静聴ありがとうございました 👋

    View Slide