Инструментарий базы данных

Чтобы помочь вам понять запросы, создаваемые вашим кодом, и управлять ими, Django предоставляет точку доступа для установки функций оболочки для выполнения запросов к базе данных. Например, эти функции могут подсчитывать запросы, измерять их продолжительность, регистрировать их или даже предотвращать их выполнение (например, чтобы гарантировать, что никакие запросы не выполняются при рендеринге шаблона с предварительно загруженными данными.

Обволакивающие функции структурированы как промежуточное ПО - они представляют собой исполняемые объекты, которые принимают другой исполняемый файл в одном из своих параметров. Они вызывают последний, чтобы вызвать (потенциально обернутый) запрос к базе данных, и они могут делать все, что захотят, вокруг этого вызова. Однако они создаются и устанавливаются пользовательским кодом, поэтому им не нужна отдельная фабрика, как в случае с промежуточным программным обеспечением.

Установка функции оболочки выполняется в диспетчере контекста, который делает эти функции временными и специфичными для определенного потока вашего кода.

Как упоминалось выше, примером функции упаковки является блокировщик выполнения запроса. Вот как это может выглядеть

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 - строка str , SQL-запрос, который будет отправлен в базу данных.
  • params - список (или кортеж) параметров, предназначенных для команды SQL, или список списков, если есть обернутый вызов executemany() .
  • many - логическое значение, указывающее, будет ли вызываемый в конце вызов execute() или executemany()params должен ли он быть списком значений или списком списков значений).
  • context - словарь с дополнительными данными о контексте вызова. Это включает в себя connection и элементы cursor .

Используя параметры, чуть более сложная версия блокировщика может включать имя соединения в сообщение об ошибке.

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.monotonic()
        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.monotonic() - 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 - исполняемый объект, принимающий пять параметров. Это вызывается при каждом выполнении запроса в рамках менеджера контекста, с аргументами execute , sql , params , many и context , как описано выше. Этот исполняемый файл должен вызывать и возвращать возвращаемое значение этого вызова.execute(sql, params, many, context)

Copyright ©2020 All rights reserved