{"title":"Instrumentering av databaser","version":"5.2","locale":"sv","docname":"topics/db/instrumentation","url":"/sv/5.2/topics/db/instrumentation/","canonical":"https://djangodocs.dev/sv/5.2/topics/db/instrumentation/","summary":"För att hjälpa dig att förstå och kontrollera de frågor som utfärdas av din kod tillhandahåller Django en hook för att installera omslagsfunktioner runt…","html":"<h1>Instrumentering av databaser<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>För att hjälpa dig att förstå och kontrollera de frågor som utfärdas av din kod tillhandahåller Django en hook för att installera omslagsfunktioner runt exekveringen av databasfrågor. Till exempel kan wrappers räkna frågor, mäta frågans varaktighet, logga frågor eller till och med förhindra frågeexekvering (t.ex. för att se till att inga frågor utfärdas när du renderar en mall med förhämtade data).</p>\n<p>Omslagen är modellerade efter <a class=\"reference internal\" href=\"/sv/5.2/topics/http/middleware/\"><span class=\"doc\">middleware</span></a> – de är anropsbara som tar en annan anropsbar som ett av sina argument. De anropar den anropsbara för att anropa databasfrågan (eventuellt inkapslad), och de kan göra vad de vill runt det anropet. De skapas och installeras dock av användarkoden och behöver därför inte en separat fabrik som middleware gör.</p>\n<p>Installationen av en wrapper görs i en kontexthanterare - så wrappers är tillfälliga och specifika för ett visst flöde i din kod.</p>\n<p>Som nämnts ovan är ett exempel på en wrapper en query execution blocker. Det skulle kunna se ut så här:</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>Och det skulle användas i en vy för att blockera frågor från mallen så här:</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>De parametrar som skickas till wrappers är:</p>\n<ul class=\"simple\">\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">execute</span></code> – en anropsbar, som ska anropas med resten av parametrarna för att utföra frågan.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">sql</span></code> – en <code class=\"docutils literal notranslate\"><span class=\"pre\">str</span></code>, SQL-frågan som ska skickas till databasen.</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code> – en lista/tupel av parametervärden för SQL-kommandot, eller en lista/tupel av listor/tuplar om det omslutna anropet är <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> – en <code class=\"docutils literal notranslate\"><span class=\"pre\">bool</span></code> som anger om det sista anropet är <code class=\"docutils literal notranslate\"><span class=\"pre\">execute()</span></code> eller <code class=\"docutils literal notranslate\"><span class=\"pre\">executemany()</span></code> (och om <code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code> förväntas vara en sekvens av värden, eller en sekvens av sekvenser av värden).</p></li>\n<li><p><code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> – en ordbok med ytterligare data om kontexten för anropet. Detta inkluderar anslutningen och markören.</p></li>\n</ul>\n<p>Med hjälp av parametrarna kan en något mer komplex version av blockeraren inkludera anslutningsnamnet i felmeddelandet:</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>För ett mer komplett exempel kan en frågeloggare se ut så här:</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>För att använda detta skapar du ett logger-objekt och installerar det som en wrapper:</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\">anslutning.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>Returnerar en kontexthanterare som, när den anges, installerar en omslagsdel runt exekveringar av databasfrågor, och när den avslutas, tar bort omslagsdelen. Omslaget installeras på det trådlokala anslutningsobjektet.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">wrapper</span></code> är en anropbar funktion som tar fem argument.  Den anropas för varje frågeexekvering i kontexthanterarens omfattning, med argumenten <code class=\"docutils literal notranslate\"><span class=\"pre\">execute</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">ql</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">params</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">many</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">context</span></code> enligt beskrivningen ovan. Den förväntas anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">execute(sql,</span> <span class=\"pre\">params,</span> <span class=\"pre\">many,</span> <span class=\"pre\">context)</span></code> och returnera returvärdet av det anropet.</p>\n</section>","rootId":"database-instrumentation","toc":[{"title":"anslutning.execute_wrapper()","anchor":"connection-execute-wrapper","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Använda Django","url":"/sv/5.2/topics/"},{"docname":"topics/db/index","title":"Modeller och databaser","url":"/sv/5.2/topics/db/"}],"prev":{"docname":"topics/db/optimization","title":"Optimering av databasåtkomst","url":"/sv/5.2/topics/db/optimization/"},"next":{"docname":"topics/db/fixtures","title":"Fixturer","url":"/sv/5.2/topics/db/fixtures/"},"formats":{"html":"/sv/5.2/topics/db/instrumentation/","markdown":"/sv/5.2/topics/db/instrumentation.md","json":"/sv/5.2/topics/db/instrumentation.json"},"source":"https://github.com/django/django/blob/stable/5.2.x/docs/topics/db/instrumentation.txt","official":"https://docs.djangoproject.com/sv/5.2/topics/db/instrumentation/","inVersions":["6.1","6.0","5.2"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}