{"title":"データベースの計測","version":"5.0","locale":"ja","docname":"topics/db/instrumentation","url":"/ja/5.0/topics/db/instrumentation/","canonical":"https://djangodocs.dev/ja/5.0/topics/db/instrumentation/","summary":"コードから発行されたクエリを理解して制御するために、Django は、データベースクエリの実行周辺にラッパー関数をインストールするためのフックを提供しています。たとえば、ラッパーは、クエリのカウント、クエリの実行時間の測定、クエリのログ、さらにクエリの実行の防止までもできます…","html":"<h1>データベースの計測<a class=\"heading-anchor\" href=\"#database-instrumentation\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>コードから発行されたクエリを理解して制御するために、Django は、データベースクエリの実行周辺にラッパー関数をインストールするためのフックを提供しています。たとえば、ラッパーは、クエリのカウント、クエリの実行時間の測定、クエリのログ、さらにクエリの実行の防止までもできます (たとえば、プリフェッチされたデータを使用してテンプレートをレンダリングする間にクエリが発行されないようにするため)。</p>\n<p>ラッパーは <a class=\"reference internal\" href=\"/ja/5.0/topics/http/middleware/\"><span class=\"doc\">ミドルウェア</span></a> にならったもので、別の呼び出し可能オブジェクトを引数の1つとして受け取ります。ラッパーはデータベースクエリ(ラップされている可能性があります)を呼び出すために callable を呼び出します。しかし、これらはユーザーコードによって作成され、インストールされるため、ミドルウェアのように個別のファクトリを必要としません。</p>\n<p>ラッパーのインストールは、コンテキストマネージャで行われます。そのため、ラッパーは一時的なもので、コード内の特定のフローに特化したものです。</p>\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=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">blocker</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">args</span><span class=\"p\">):</span>\n    <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s2\">&quot;No database access allowed here.&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\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\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">connection</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">render</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"o\">...</span><span class=\"p\">}</span>  <span class=\"c1\"># Code to generate context with all data.</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"o\">...</span>\n    <span class=\"k\">with</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">execute_wrapper</span><span class=\"p\">(</span><span class=\"n\">blocker</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"n\">template_name</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>ラッパーに送られるパラメーターは以下の通りです:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">execute</span></code> -- クエリを実行するために、残りのパラメータと一緒に呼び出される呼び出し可能オブジェクト。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">sql</span></code> -- データベースに送信する SQL クエリの <code class=\"docutils literal notranslate\"><span class=\"pre\">str</span></code>。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code> -- SQL コマンドのパラメータ値のリストまたはタプル、または、ラップされた呼び出しが <code class=\"docutils literal notranslate\"><span class=\"pre\">executemany()</span></code> の場合はリストまたはタプルのリストまたはタプル。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">many</span></code> -- 最終的に呼び出すのが <code class=\"docutils literal notranslate\"><span class=\"pre\">execute()</span></code> なのか <code class=\"docutils literal notranslate\"><span class=\"pre\">executemany()</span></code> なのかを示す <code class=\"docutils literal notranslate\"><span class=\"pre\">bool</span></code> (<code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code> が値のシーケンスなのか、値のシーケンスのシーケンスなのかを示します)。</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> -- 呼び出しのコンテキストに関するデータを含む辞書。これにはコネクションとカーソルが含まれます。</p></li>\n</ul>\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=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">blocker</span><span class=\"p\">(</span><span class=\"n\">execute</span><span class=\"p\">,</span> <span class=\"n\">sql</span><span class=\"p\">,</span> <span class=\"n\">params</span><span class=\"p\">,</span> <span class=\"n\">many</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n    <span class=\"n\">alias</span> <span class=\"o\">=</span> <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s2\">&quot;connection&quot;</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">alias</span>\n    <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s2\">&quot;Access to database &#39;</span><span class=\"si\">{}</span><span class=\"s2\">&#39; blocked here&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">alias</span><span class=\"p\">))</span>\n</code></pre></div>\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\">import</span><span class=\"w\"> </span><span class=\"nn\">time</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">QueryLogger</span><span class=\"p\">:</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">queries</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__call__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">execute</span><span class=\"p\">,</span> <span class=\"n\">sql</span><span class=\"p\">,</span> <span class=\"n\">params</span><span class=\"p\">,</span> <span class=\"n\">many</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">):</span>\n        <span class=\"n\">current_query</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;sql&quot;</span><span class=\"p\">:</span> <span class=\"n\">sql</span><span class=\"p\">,</span> <span class=\"s2\">&quot;params&quot;</span><span class=\"p\">:</span> <span class=\"n\">params</span><span class=\"p\">,</span> <span class=\"s2\">&quot;many&quot;</span><span class=\"p\">:</span> <span class=\"n\">many</span><span class=\"p\">}</span>\n        <span class=\"n\">start</span> <span class=\"o\">=</span> <span class=\"n\">time</span><span class=\"o\">.</span><span class=\"n\">monotonic</span><span class=\"p\">()</span>\n        <span class=\"k\">try</span><span class=\"p\">:</span>\n            <span class=\"n\">result</span> <span class=\"o\">=</span> <span class=\"n\">execute</span><span class=\"p\">(</span><span class=\"n\">sql</span><span class=\"p\">,</span> <span class=\"n\">params</span><span class=\"p\">,</span> <span class=\"n\">many</span><span class=\"p\">,</span> <span class=\"n\">context</span><span class=\"p\">)</span>\n        <span class=\"k\">except</span> <span class=\"ne\">Exception</span> <span class=\"k\">as</span> <span class=\"n\">e</span><span class=\"p\">:</span>\n            <span class=\"n\">current_query</span><span class=\"p\">[</span><span class=\"s2\">&quot;status&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;error&quot;</span>\n            <span class=\"n\">current_query</span><span class=\"p\">[</span><span class=\"s2\">&quot;exception&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">e</span>\n            <span class=\"k\">raise</span>\n        <span class=\"k\">else</span><span class=\"p\">:</span>\n            <span class=\"n\">current_query</span><span class=\"p\">[</span><span class=\"s2\">&quot;status&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;ok&quot;</span>\n            <span class=\"k\">return</span> <span class=\"n\">result</span>\n        <span class=\"k\">finally</span><span class=\"p\">:</span>\n            <span class=\"n\">duration</span> <span class=\"o\">=</span> <span class=\"n\">time</span><span class=\"o\">.</span><span class=\"n\">monotonic</span><span class=\"p\">()</span> <span class=\"o\">-</span> <span class=\"n\">start</span>\n            <span class=\"n\">current_query</span><span class=\"p\">[</span><span class=\"s2\">&quot;duration&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">duration</span>\n            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">queries</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">current_query</span><span class=\"p\">)</span>\n</code></pre></div>\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\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">connection</span>\n\n<span class=\"n\">ql</span> <span class=\"o\">=</span> <span class=\"n\">QueryLogger</span><span class=\"p\">()</span>\n<span class=\"k\">with</span> <span class=\"n\">connection</span><span class=\"o\">.</span><span class=\"n\">execute_wrapper</span><span class=\"p\">(</span><span class=\"n\">ql</span><span class=\"p\">):</span>\n    <span class=\"n\">do_queries</span><span class=\"p\">()</span>\n<span class=\"c1\"># Now we can print the log.</span>\n<span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"n\">ql</span><span class=\"o\">.</span><span class=\"n\">queries</span><span class=\"p\">)</span>\n</code></pre></div>\n<section id=\"connection-execute-wrapper\">\n<h2><code class=\"docutils literal notranslate\"><span class=\"pre\">connection.execute_wrapper()</span></code><a class=\"heading-anchor\" href=\"#connection-execute-wrapper\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.db.backends.base.DatabaseWrapper.execute_wrapper\">\n<span class=\"sig-name descname\"><span class=\"pre\">execute_wrapper</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">wrapper</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.db.backends.base.DatabaseWrapper.execute_wrapper\"><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<p><code class=\"docutils literal notranslate\"><span class=\"pre\">wrapper</span></code> は5つの引数を取る呼び出し可能オブジェクトです。 上記のように、 <code class=\"docutils literal notranslate\"><span class=\"pre\">execute</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">sql</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">many</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> を引数として、コンテキストマネージャのスコープ内でクエリを実行するたびに呼び出されます。 <code class=\"docutils literal notranslate\"><span class=\"pre\">execute(sql、params、many、context)</span></code> を呼び出して、その戻り値を返すことが期待されます。</p>\n</section>","rootId":"database-instrumentation","toc":[{"title":"connection.execute_wrapper()","anchor":"connection-execute-wrapper","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/5.0/topics/"},{"docname":"topics/db/index","title":"モデルとデータベース","url":"/ja/5.0/topics/db/"}],"prev":{"docname":"topics/db/optimization","title":"データベースアクセスの最適化","url":"/ja/5.0/topics/db/optimization/"},"next":{"docname":"topics/db/fixtures","title":"フィクスチャ (fixture)","url":"/ja/5.0/topics/db/fixtures/"},"formats":{"html":"/ja/5.0/topics/db/instrumentation/","markdown":"/ja/5.0/topics/db/instrumentation.md","json":"/ja/5.0/topics/db/instrumentation.json"},"source":"https://github.com/django/django/blob/stable/5.0.x/docs/topics/db/instrumentation.txt","official":"https://docs.djangoproject.com/ja/5.0/topics/db/instrumentation/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}