Django 2.1 - Database instrumentation

डेटाबेस इंस्ट्रूमेंटेशन




django

डेटाबेस इंस्ट्रूमेंटेशन

Django 2.0 में नया:

अपने कोड द्वारा जारी किए गए प्रश्नों को समझने और नियंत्रित करने में आपकी मदद करने के लिए, Django डेटाबेस प्रश्नों के निष्पादन के आसपास आवरण कार्यों को स्थापित करने के लिए एक हुक प्रदान करता है। उदाहरण के लिए, रैपर प्रश्नों की गणना कर सकते हैं, क्वेरी अवधि को माप सकते हैं, प्रश्नों को लॉग कर सकते हैं, या क्वेरी निष्पादन को भी रोक सकते हैं (उदाहरण के लिए यह सुनिश्चित करें कि प्रीफ़ेटेड डेटा के साथ टेम्पलेट रेंडर करते समय कोई प्रश्न जारी नहीं किए गए हैं)।

रैपर middleware बाद तैयार किए जाते हैं - वे कॉलबल्स होते हैं जो एक और कॉल करने योग्य को उनके तर्कों के रूप में लेते हैं। वे (संभवतः लिपटे हुए) डेटाबेस क्वेरी को लागू करने के लिए उस कॉल करने योग्य को कॉल करते हैं, और वे उस कॉल के चारों ओर जो चाहते हैं वह कर सकते हैं। हालाँकि, वे उपयोगकर्ता कोड द्वारा निर्मित और स्थापित किए जाते हैं, और इसलिए मिडलवेयर जैसे अलग कारखाने की आवश्यकता नहीं होती है।

एक आवरण स्थापित करना एक संदर्भ प्रबंधक में किया जाता है - इसलिए आवरण आपके कोड में कुछ प्रवाह के लिए अस्थायी और विशिष्ट होते हैं।

जैसा कि ऊपर उल्लेख किया गया है, एक आवरण का एक उदाहरण एक क्वेरी निष्पादन अवरोधक है। यह इस तरह दिख सकता है:

def blocker(*args):
    raise Exception('No database access allowed here.')

और यह इस तरह से टेम्पलेट से प्रश्नों को ब्लॉक करने के लिए एक दृश्य में इस्तेमाल किया जाएगा:

from django.db import connection
from django.shortcuts import render

def my_view(request):
    context = {...}  # Code to generate context with all data.
    template_name = ...
    with connection.execute_wrapper(blocker):
        return render(request, template_name, context)

रैपरों को भेजे गए पैरामीटर निम्न हैं:

  • execute - एक कॉल करने योग्य, जिसे क्वेरी को निष्पादित करने के लिए बाकी मापदंडों के साथ लागू किया जाना चाहिए।
  • sql - a str , SQL क्वेरी को डेटाबेस में भेजा जाना है।
  • params - एसक्यूएल कमांड के लिए पैरामीटर मानों की एक सूची / ट्यूपल, या लिस्ट / ट्यूपल की एक सूची / ट्यूपल यदि लिपटे हुए कॉल executemany()
  • many - एक bool जो दर्शाता है कि क्या अंततः कॉल किया गया है execute() या executemany() और (क्या executemany() को मूल्यों का अनुक्रम होने की उम्मीद है, या मूल्यों के अनुक्रम का एक क्रम)।
  • context - आह्वान के संदर्भ के बारे में आगे के आंकड़ों के साथ एक शब्दकोश। इसमें कनेक्शन और कर्सर शामिल हैं।

मापदंडों का उपयोग करते हुए, अवरोधक का थोड़ा और अधिक जटिल संस्करण त्रुटि संदेश में कनेक्शन का नाम शामिल कर सकता है:

def blocker(execute, sql, params, many, context):
    alias = context['connection'].alias
    raise Exception("Access to database '{}' blocked here".format(alias))

अधिक पूर्ण उदाहरण के लिए, एक क्वेरी लकड़हारा इस तरह दिख सकता है:

import time

class QueryLogger:

    def __init__(self):
        self.queries = []

    def __call__(self, execute, sql, params, many, context):
        current_query = {'sql': sql, 'params': params, 'many': many}
        start = time.time()
        try:
            result = execute(sql, params, many, context)
        except Exception as e:
            current_query['status'] = 'error'
            current_query['exception'] = e
            raise
        else:
            current_query['status'] = 'ok'
            return result
        finally:
            duration = time.time() - start
            current_query['duration'] = duration
            self.queries.append(current_query)

इसका उपयोग करने के लिए, आप एक लकड़हारा वस्तु बनाएंगे और इसे एक आवरण के रूप में स्थापित करेंगे:

from django.db import connection

ql = QueryLogger()
with connection.execute_wrapper(ql):
    do_queries()
# Now we can print the log.
print(ql.queries)

connection.execute_wrapper()

execute_wrapper(wrapper)

एक संदर्भ प्रबंधक देता है, जो दर्ज किए जाने पर, डेटाबेस क्वेरी निष्पादन के चारों ओर एक आवरण स्थापित करता है, और जब बाहर निकलता है, तो आवरण हटाता है। आवरण थ्रेड-स्थानीय कनेक्शन ऑब्जेक्ट पर स्थापित किया गया है।

wrapper एक तर्क है जिसमें पाँच तर्क दिए जाते हैं। इसे संदर्भ प्रबंधक के कार्यक्षेत्र में प्रत्येक क्वेरी के निष्पादन के लिए कहा जाता है, तर्कों के साथ, sql , params , many , और context जैसा कि ऊपर वर्णित है। यह execute(sql, params, many, context) को कॉल execute(sql, params, many, context) और उस कॉल के रिटर्न मान को वापस करने की उम्मीद है।