{"title":"非同期サポート","version":"4.2","locale":"ja","docname":"topics/async","url":"/ja/4.2/topics/async/","canonical":"https://djangodocs.dev/ja/4.2/topics/async/","summary":"Djangoは、 ASGI の環境下であれば、完璧な非同期リクエストスタックに対応した非同期 (\"async\") ビューをサポートしています。WSGIの環境下でも非同期ビューは動作しますが、パフォーマンス上不利であるうえ、長期的なリクエストを効率的に処理できません。…","html":"<h1>非同期サポート<a class=\"heading-anchor\" href=\"#asynchronous-support\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Djangoは、<a class=\"reference internal\" href=\"/ja/4.2/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a> の環境下であれば、完璧な非同期リクエストスタックに対応した非同期 (&quot;async&quot;) ビューをサポートしています。WSGIの環境下でも非同期ビューは動作しますが、パフォーマンス上不利であるうえ、長期的なリクエストを効率的に処理できません。</p>\n<p>開発チームはORMや他の機能でも非同期処理が対応できるよう取り組んでいます。この機能は将来リリース予定ですが、現時点では、同期処理と非同期処理のやり取りに、 <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> アダプターが使えます。さらに同期処理と非同期処理を統合するために、非同期なPythonライブラリがすべて使えます。</p>\n<section id=\"async-views\">\n<h2>非同期ビュー<a class=\"heading-anchor\" href=\"#async-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>どのようなビューでも、呼び出し可能オブジェクトでコルーチンを返すようにすれば、非同期として宣言できます。その際には、一般的に <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> を使います。関数ベースのビューの場合、<code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> を用いてビュー全体を宣言します。クラスベースのビューの場合、<code class=\"docutils literal notranslate\"><span class=\"pre\">get()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">post()</span></code> などのメソッドを <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code> で宣言します (<code class=\"docutils literal notranslate\"><span class=\"pre\">__init__()</span></code> でも <code class=\"docutils literal notranslate\"><span class=\"pre\">as_view()</span></code> でもないことに注意)。</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>Djangoはあなたのビューが非同期かどうか確かめるために``asgiref.sync.iscoroutinefunction``を使います。もし、コルーチンを返すあなた独自のメソッドを実装する場合は、確実に``asgiref.sync.markcoroutinefunction`` を用いて``asgiref.sync.iscoroutinefunction``がTrueを返すようにして下さい。</p>\n</aside>\n<p>WSGIサーバーでは、非同期ビューは1回限りのイベントループで実行されます。つまり、非同期HTTPリクエストなどの非同期機能を問題なく使用できるものの、非同期スタックのメリットは得られないことになります。</p>\n<p>非同期スタックの主な利点とは、数百もの接続をPythonのスレッドを使わずに処理できることです。これにより、低速ストリーミング、ロングポーリング、その他の便利なレスポンスタイプが使えます。</p>\n<p>もしこれらを利用したい場合は、代わりに <a class=\"reference internal\" href=\"/ja/4.2/howto/deployment/asgi/\"><span class=\"doc\">ASGI</span></a> を使ってDjangoをデプロイする必要があります。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>同期ミドルウェアを使っていない場合にのみ、完全非同期のリクエストスタックの効果があります。もし、同期ミドルウェアがあれば、同期環境を安全にエミュレートするために、Djangoはリクエストごとにスレッドを使ってしまいます。</p>\n<p>ミドルウェアは、<a class=\"reference internal\" href=\"/ja/4.2/topics/http/middleware/#async-middleware\"><span class=\"std std-ref\">both sync and async</span></a> コンテキストをサポートするように構築できます。 Djangoミドルウェアの一部はこのように構築されていますが、すべてではありません。ミドルウェアが適応する必要があるものを確認するには、 <code class=\"docutils literal notranslate\"><span class=\"pre\">django.request</span></code> ロガーのデバッグロギングを有効にして、 <em>&quot;Asynchronous handler adapted for middleware ...&quot;</em> に関するログメッセージを探します。</p>\n</aside>\n<p>ASGIとWSGIの両方のモードで、非同期サポートを使用し、シリアルではなく並行してコードを実行することができます。これは特に、外部APIやデータストアを扱う場合に便利です。</p>\n<p>まだ同期的なDjangoの機能を呼び出したい場合、次のように <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> でラップする必要があります。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"n\">results</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)(</span><span class=\"n\">pk</span><span class=\"o\">=</span><span class=\"mi\">123</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>非同期ビューから、同期的なDjangoの機能を誤って呼び出そうとすると、Djangoの&lt;async-safety&gt;が発動して、データが破損しないように保護されます。</p>\n<section id=\"queries-the-orm\">\n<h3>クエリーとORM<a class=\"heading-anchor\" href=\"#queries-the-orm\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"version-note version-added\" data-version=\"4.1\">\n<p class=\"version-note-title\">New in Django 4.1</p></aside>\n<p>一部の例外を除いて、DjangoはORMクエリーを非同期に実行することもできます。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">for</span> <span class=\"n\">author</span> <span class=\"ow\">in</span> <span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">name__startswith</span><span class=\"o\">=</span><span class=\"s2\">&quot;A&quot;</span><span class=\"p\">):</span>\n    <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">author</span><span class=\"o\">.</span><span class=\"n\">books</span><span class=\"o\">.</span><span class=\"n\">afirst</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>詳細については <a class=\"reference internal\" href=\"/ja/4.2/topics/db/queries/#async-queries\"><span class=\"std std-ref\">Asynchronous queries</span></a> で参照できますが、簡単にまとめると次のようになります。</p>\n<ul class=\"simple\">\n<li><p>SQLクエリを発行するすべての <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> メソッドには、<code class=\"docutils literal notranslate\"><span class=\"pre\">a</span></code> という接頭辞が付いた非同期版があります。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">for</span></code> は (<code class=\"docutils literal notranslate\"><span class=\"pre\">values()</span></code> と <code class=\"docutils literal notranslate\"><span class=\"pre\">values_list()</span></code> を含む) すべてのQuerySetsでサポートされている</p></li>\n</ul>\n<p>Django は、次のような非同期モデルのデータベースを使用するメソッドもいくつかサポートします。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">make_book</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"k\">await</span> <span class=\"n\">book</span><span class=\"o\">.</span><span class=\"n\">asave</span><span class=\"p\">(</span><span class=\"n\">using</span><span class=\"o\">=</span><span class=\"s2\">&quot;secondary&quot;</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">make_book_with_tags</span><span class=\"p\">(</span><span class=\"n\">tags</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"n\">book</span> <span class=\"o\">=</span> <span class=\"k\">await</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">acreate</span><span class=\"p\">(</span><span class=\"o\">...</span><span class=\"p\">)</span>\n    <span class=\"k\">await</span> <span class=\"n\">book</span><span class=\"o\">.</span><span class=\"n\">tags</span><span class=\"o\">.</span><span class=\"n\">aset</span><span class=\"p\">(</span><span class=\"n\">tags</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>トランザクションは非同期モードではまだ機能しません。もしトランザクションの動作が必要なコードがある場合は、そのコードを1つの同期的な関数として書いて、<a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> を使用して呼び出すことをおすすめします。</p>\n<aside class=\"version-note version-changed\" data-version=\"4.2\">\n<p class=\"version-note-title\">Changed in Django 4.2</p><p>非同期モデルと関連するマネージャーインターフェイスが追加されました。</p>\n</aside>\n</section>\n<section id=\"performance\">\n<h3>パフォーマンス<a class=\"heading-anchor\" href=\"#performance\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>ビューと異なるモードで実行 (たとえば、非同期のビューを WSGI で実行、従来の同期ビューを ASGI で実行) した場合、Django はコードを実行するために、もう一方の呼び出しスタイルをエミュレートする必要があります。コンテクストスイッチにより、1 ms 程度の小さな性能上のペナルティが与えられてしまいます。</p>\n<p>これはミドルウェアでも同様です。Django は同期・非同期の間のコンテクストスイッチの数を最小化するように試みます。もし ASGI サーバーがあっても、すべてのミドルウェアとビューが同期的だった場合、コンテクストスイッチは、サーバーがミドルウェアスタックに入る前の1回だけです。</p>\n<p>しかし、同期ミドルウェアをASGIサーバーと非同期ビューの間においた場合、サーバーはミドルウェアのために同期モードに切り替え、ビューのために非同期モードにまた戻さなければならなくなります。Django はミドルウェアの例外の伝搬のために同期スレッドも保持し続けます。これは初めは気づかないほどの違いかもしれませんが、1リクエストごとに1スレッドのペナルティが与えられると、非同期の性能上の利点がすべて打ち消されてしまう可能性があります。</p>\n<p>自分のコード上での ASGI と WSGI の違いの影響を知るためには、自分自身でパフォーマンステストを行うべきです。場合によっては、純粋に同期的なコードベースを ASGI 上で実行した場合でも、性能が向上することがあります。これは、それでもリクエストハンドリングのコードはすべて非同期に実行されるためです。一般的には、ASGI モードを有効にする必要があるのは、プロジェクトに非同期のコードがあるときだけです。</p>\n</section>\n</section>\n<section id=\"async-safety\">\n<span id=\"id1\"></span><h2>非同期安全性<a class=\"heading-anchor\" href=\"#async-safety\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"std envvar\">\n<dt class=\"sig sig-object std\" id=\"envvar-DJANGO_ALLOW_ASYNC_UNSAFE\">\n<span class=\"sig-name descname\"><span class=\"pre\">DJANGO_ALLOW_ASYNC_UNSAFE</span></span><a class=\"heading-anchor\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Django の特定の主要なパーツは、コルーチンが感知できないグローバルステートを持つため、非同期の環境では安全に操作できません。これらの Django のパーツは、&quot;async-unsafe&quot; として分類されており、非同期な環境での実行から保護されています。ORM は主な例ですが、この他にもこのように保護されているパーツがあります。</p>\n<p>If you try to run any of these parts from a thread where there is a <em>running\nevent loop</em>, you will get a\n<a class=\"reference internal\" href=\"/ja/4.2/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SynchronousOnlyOperation</span></code></a> error. Note that you\ndon't have to be inside an async function directly to have this error occur. If\nyou have called a sync function directly from an async function,\nwithout using <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> or similar, then it can also occur. This is\nbecause your code is still running in a thread with an active event loop, even\nthough it may not be declared as async code.</p>\n<p>このエラーが発生した場合は、問題のコードを非同期コンテキストから呼び出さないように修正する必要があります。代わりに、独自の同期関数それ自体の中で async-unsafe と通信するコードを書き、  <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asgiref.sync.sync_to_async()</span></code></a> (または、自スレッド内で同期コードを実行するための他の方法) を使って呼び出します。</p>\n<p>非同期コンテキストは、Django コードを実行している環境によって与えられる場合もあります。たとえば、<a class=\"reference external\" href=\"https://jupyter.org/\">Jupyter</a> notebooks や <a class=\"reference external\" href=\"https://ipython.org\">IPython</a> 対話シェルはともにアクティブなイベントループを透過的に提供してくれるため、非同期 API との対話がより簡単になります。</p>\n<p>もし IPython shell を使用している場合は、次のコマンドでこのイベントループを無効化できます。</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code>%autoawait<span class=\"w\"> </span>off\n</code></pre></div>\n<p>これは IPython のプロンプトのコマンドです。これにより同期的なコードを <a class=\"reference internal\" href=\"/ja/4.2/ref/exceptions/#django.core.exceptions.SynchronousOnlyOperation\" title=\"django.core.exceptions.SynchronousOnlyOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SynchronousOnlyOperation</span></code></a> エラーを起こさずに実行できるようになりますが、同時に、非同期 API を <code class=\"docutils literal notranslate\"><span class=\"pre\">await</span></code> することもできなくなります。イベントループを戻すには、次のコマンドを実行します。</p>\n<div class=\"code-block\" data-language=\"shell\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Shell</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Shell code\"><code>%autoawait<span class=\"w\"> </span>on\n</code></pre></div>\n<p>IPython 以外の環境にいる場合 (または、何らかの理由で IPython で <code class=\"docutils literal notranslate\"><span class=\"pre\">autoawait</span></code> がオフにできない場合)、コードが並行して実行される可能性は*確実に*ないため、同期コードは*絶対に*非同期コンテキストから実行する必要があります。このとき、警告は <span class=\"target\" id=\"index-2\"></span><a class=\"reference internal\" href=\"#envvar-DJANGO_ALLOW_ASYNC_UNSAFE\"><code class=\"xref std std-envvar docutils literal notranslate\"><span class=\"pre\">DJANGO_ALLOW_ASYNC_UNSAFE</span></code></a> 環境変数を任意の値に設定することで無効化できます。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>このオプションを有効にした上で、Djangoの  async-unsafe パーツへ同時アクセスがあると、データが失われたり壊れたりする可能性があります。十分な注意を払い、本番環境では使用しないでください。</p>\n</aside>\n<p>もし、これをPython内部から行いたい場合は、 <code class=\"docutils literal notranslate\"><span class=\"pre\">os.environ</span></code>:: を使用してください。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">os</span>\n\n<span class=\"n\">os</span><span class=\"o\">.</span><span class=\"n\">environ</span><span class=\"p\">[</span><span class=\"s2\">&quot;DJANGO_ALLOW_ASYNC_UNSAFE&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;true&quot;</span>\n</code></pre></div>\n</section>\n<section id=\"async-adapter-functions\">\n<h2>非同期アダプター関数<a class=\"heading-anchor\" href=\"#async-adapter-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>同期コードを非同期コンテキストから呼び出したり、その逆をするためには、呼び出しスタイルを調整する必要があります。このために、<code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref.sync</span></code> モジュールの <a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> と <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> という2つのアダプター関数があります。これらは互換性を維持したまま呼び出しスタイル間を移行するために使われます。</p>\n<p>これらのアダプター関数は Django で幅広く利用されています。<a class=\"extlink-pypi reference external\" href=\"https://pypi.org/project/asgiref/\">asgiref</a> パッケージ自体が Django プロジェクトの一部になっており、Django を <code class=\"docutils literal notranslate\"><span class=\"pre\">pip</span></code> でインストールしたときに自動的に依存関係としてインストールされます。</p>\n<section id=\"async-to-sync\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code><a class=\"heading-anchor\" href=\"#async-to-sync\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"asgiref.sync.async_to_sync\">\n<span class=\"sig-name descname\"><span class=\"pre\">async_to_sync</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">async_function</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">force_new_loop</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">False</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.async_to_sync\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>非同期関数を取り、それをラッピングした同期関数を返します。直接ラッパーとしてもデコレーターとしても使用できます。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">async_to_sync</span>\n\n\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_data</span><span class=\"p\">():</span>\n    <span class=\"o\">...</span>\n\n\n<span class=\"n\">sync_get_data</span> <span class=\"o\">=</span> <span class=\"n\">async_to_sync</span><span class=\"p\">(</span><span class=\"n\">get_data</span><span class=\"p\">)</span>\n\n\n<span class=\"nd\">@async_to_sync</span>\n<span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_other_data</span><span class=\"p\">():</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>非同期関数は、もし存在すれば、現在のスレッドのイベントループの中で実行されます。現在のイベントループが存在しない場合、1つの非同期呼び出しのために専用の新しいイベントループが生成され、完了したら再び破棄されます。どちらの状況でも、非同期関数はコードが呼び出されたスレッドとは異なるスレッドで実行されます。</p>\n<p>threadlocals および contextvars の値は境界を越えて両方向に保持されます。</p>\n<p><a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> は、本質的に Python 標準ライブラリの <a class=\"reference external\" href=\"https://docs.python.org/3/library/asyncio-runner.html#asyncio.run\" title=\"(in Python v3.14)\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code></a> 関数のより強力なバージョンです。threadlocals が確実に動作するようにするだけでなく、it also enables the <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> mode of <a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> when that wrapper is used below it.</p>\n</section>\n<section id=\"sync-to-async\">\n<h3><code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code><a class=\"heading-anchor\" href=\"#sync-to-async\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"asgiref.sync.sync_to_async\">\n<span class=\"sig-name descname\"><span class=\"pre\">sync_to_async</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sync_function</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">thread_sensitive</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#asgiref.sync.sync_to_async\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>同期関数を取り、それをラッピングした非同期関数を返します。直接ラッパーとしてもデコレーターとしても使用できます。</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n\n<span class=\"n\">async_function</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">False</span><span class=\"p\">)</span>\n<span class=\"n\">async_function</span> <span class=\"o\">=</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">sensitive_sync_function</span><span class=\"p\">,</span> <span class=\"n\">thread_sensitive</span><span class=\"o\">=</span><span class=\"kc\">True</span><span class=\"p\">)</span>\n\n\n<span class=\"nd\">@sync_to_async</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">sync_function</span><span class=\"p\">():</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>threadlocals および contextvars の値は境界を越えて両方向に保持されます。</p>\n<p>同期関数はすべてメインスレッド内で実行されることを想定して書かれる傾向があるため、<a class=\"reference internal\" href=\"#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> には2種類の threading モードがあります。</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive=True</span></code> (デフォルト): 同期関数は他のすべての <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> 関数と同じスレッド内で実行されます。もしメインスレッドが同期的で <a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> ラッパーを使用している場合、このスレッドはメインスレッドになるでしょう。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive=False</span></code>: 同期関数は、まったく新しいスレッドで実行されます。そのスレッドは、その後呼び出しが完了すると閉じられます。</p></li>\n</ul>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref</span></code> バージョン 3.3.0 は <code class=\"docutils literal notranslate\"><span class=\"pre\">thread_sensitive</span></code> のデフォルト値を <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> に変更しました。これは安全側のデフォルトなので、多くの場合、正しい値で Django とインタラクションしますが、以前のバージョンから <code class=\"docutils literal notranslate\"><span class=\"pre\">asgiref</span></code> をアップデートする場合は、必ず <code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> の使用を評価してください。</p>\n</aside>\n<p>thread-sensitive モードは極めて特別なモードで、すべての関数が同一スレッドで実行されるようにするためにたくさんの仕事を行います。ただし、メインスレッドで正しく動作するように、<a href=\"#id1\"><span class=\"problematic\" id=\"id2\">*</span></a>スタック内での * <a class=\"reference internal\" href=\"#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> の使用*に依存していることに注意してください。もし <code class=\"docutils literal notranslate\"><span class=\"pre\">asyncio.run()</span></code> や類似のメソッドを使用した場合、thread-sensitive な関数は単一の共有スレッドでの実行にフォールバックしますが、これはメインスレッドではありません。</p>\n<p>Django でこれが必要な理由は、多くのライブラリ、特にデータベースアダプターが、自分が作られたのと同一スレッド内でのアクセスを必要とするためです。また、既存の多くの Django コードも、すべてが同一スレッドで実行されることを想定しています。たとえば、ビュー内で後で使用するためにリクエストに何かを追加するミドルウェアです。</p>\n<p>このコードによって潜在的な互換性の問題を引き起こす代わりに、私たちはこのモードを追加する選択をしました。これにより、既存のすべての Django の同期コードが同一スレッドで実行されるようになり、したがって、非同期モードと完全に互換になります。同期コードは、それを呼び出すすべての非同期コードとは常に*異なる*スレッド内にあるため、生のデータベースハンドルや、その他 thread-sensitive な参照を渡すことは避ける必要があることに注意してください。</p>\n<p>実用的には、この制限は、<code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> を呼び出すときにデータベースの <code class=\"docutils literal notranslate\"><span class=\"pre\">connection</span></code> オブジェクトの機能を渡してはならないことを意味します。もしそうした場合、スレッドse-huの安全性チェックがトリガーされます。</p>\n<div class=\"code-block\" data-language=\"pycon\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Python console</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Python console code\"><code><span class=\"go\"># DJANGO_SETTINGS_MODULE=settings.py python -m asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">asyncio</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">asgiref.sync</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">sync_to_async</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">connection</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># In an async context so you cannot use the database directly:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">()</span>\n<span class=\"go\">django.core.exceptions.SynchronousOnlyOperation: You cannot call this from</span>\n<span class=\"go\">an async context - use a thread or sync_to_async.</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"c1\"># Nor can you pass resolved connection attributes across threads:</span>\n<span class=\"gp\">&gt;&gt;&gt; </span><span class=\"k\">await</span> <span class=\"n\">sync_to_async</span><span class=\"p\">(</span><span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">cursor</span><span class=\"p\">)()</span>\n<span class=\"go\">django.db.utils.DatabaseError: DatabaseWrapper objects created in a thread</span>\n<span class=\"go\">can only be used in that same thread. The object with alias &#39;default&#39; was</span>\n<span class=\"go\">created in thread id 4371465600 and this is thread id 6131478528.</span>\n</code></pre></div>\n<p>代わりに、呼び出しコード内の connection オブジェクトに依存せずに、<code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> で呼び出すことができるヘルパー関数内にすべてのデータベースアクセスをカプセル化する必要があります。</p>\n</section>\n<section id=\"use-with-exception-reporting-filters\">\n<h3>例外レポートフィルターと併用する<a class=\"heading-anchor\" href=\"#use-with-exception-reporting-filters\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>同期/非同期の境界を越える必要がある仕組みのせいで、<code class=\"docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code> および <code class=\"docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code> は、例外報告からのローカル変数をマスクするのに使われる <a class=\"reference internal\" href=\"/ja/4.2/howto/error-reporting/#django.views.decorators.debug.sensitive_variables\" title=\"django.views.decorators.debug.sensitive_variables\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sensitive_variables()</span></code></a> とは互換性が**ありません**。</p>\n<p>これらのアダプターを機密性の高い変数に使用する場合は、必ず例外報告を監査し、必要に応じて <a class=\"reference internal\" href=\"/ja/4.2/howto/error-reporting/#custom-error-reports\"><span class=\"std std-ref\">カスタムフィルター</span></a> の実装を検討してください。</p>\n</aside>\n</section>\n</section>","rootId":"asynchronous-support","toc":[{"title":"非同期ビュー","anchor":"async-views","children":[{"title":"クエリーとORM","anchor":"queries-the-orm","children":[]},{"title":"パフォーマンス","anchor":"performance","children":[]}]},{"title":"非同期安全性","anchor":"async-safety","children":[]},{"title":"非同期アダプター関数","anchor":"async-adapter-functions","children":[{"title":"async_to_sync()","anchor":"async-to-sync","children":[]},{"title":"sync_to_async()","anchor":"sync-to-async","children":[]},{"title":"例外レポートフィルターと併用する","anchor":"use-with-exception-reporting-filters","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/4.2/topics/"}],"prev":{"docname":"topics/external-packages","title":"External packages","url":"/ja/4.2/topics/external-packages/"},"next":{"docname":"howto/index","title":"「How-to」ガイド","url":"/ja/4.2/howto/"},"formats":{"html":"/ja/4.2/topics/async/","markdown":"/ja/4.2/topics/async.md","json":"/ja/4.2/topics/async.json"},"source":"https://github.com/django/django/blob/stable/4.2.x/docs/topics/async.txt","official":"https://docs.djangoproject.com/ja/4.2/topics/async/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}