ابزارهای پایش و کنترل کوئری‌ها در Django: معرفی Database Query Wrappers و execute_wrapper

این مقاله نحوهٔ استفاده از قابلیت Database Instrumentation در Django را توضیح می‌دهد؛ قابلیتی که به شما اجازه می‌دهد اجرای کوئری‌ها را کنترل، ثبت، محدود یا تحلیل کنید. با استفاده از execute_wrapper می‌توان رفتار اجرای کوئری‌ها را تغییر داد، آن‌ها را لاگ کرد، مدت زمانشان را اندازه گرفت یا حتی اجرای کوئری را مسدود کرد. این مقاله ساختار wrapperها، پارامترهای ورودی، مثال‌های عملی و کاربردهای رایج را پوشش می‌دهد.

execute_wrapper، Query Logger، Database InstrumentationDjango ORM، مانیتورینگ کوئریبلاک‌کردن کوئری

~3 دقیقه مطالعه · آخرین به‌روزرسانی ۱۹ اسفند ۱۴۰۴

۱. مقدمه: Database Instrumentation در Django

Django یک قابلیت قدرتمند برای کنترل و بررسی کوئری‌های دیتابیس ارائه می‌دهد. این قابلیت به شما اجازه می‌دهد wrapperهایی روی اجرای کوئری‌ها نصب کنید تا:

  • تعداد کوئری‌ها را بشمارید
  • مدت زمان اجرای هر کوئری را اندازه بگیرید
  • کوئری‌ها را لاگ کنید
  • یا حتی اجرای کوئری را مسدود کنید

این wrapperها شبیه middleware هستند، اما مخصوص دیتابیس و فقط در محدودهٔ یک context manager فعال می‌شوند.

۲. ساختار کلی یک Wrapper

یک wrapper یک تابع یا callable است که پنج پارامتر دریافت می‌کند:

  • execute: تابعی که باید برای اجرای واقعی کوئری فراخوانی شود
  • sql: رشتهٔ SQL
  • params: پارامترهای کوئری
  • many: آیا executemany اجرا می‌شود؟
  • context: اطلاعات اضافی شامل connection و cursor

۳. مثال ساده: مسدودکنندهٔ کوئری


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

استفاده در view:


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

def my_view(request):
    context = {...}
    template_name = ...
    with connection.execute_wrapper(blocker):
        return render(request, template_name, context)

نسخهٔ پیشرفته‌تر با نام دیتابیس:


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

۴. مثال کامل: Query Logger

این logger مدت زمان اجرای هر کوئری، وضعیت و پارامترها را ثبت می‌کند.


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()

print(ql.queries)

۵. متد execute_wrapper

connection.execute_wrapper(wrapper) یک context manager برمی‌گرداند که:

  • در زمان ورود، wrapper را فعال می‌کند
  • در زمان خروج، آن را غیرفعال می‌کند
  • فقط روی همان connection و همان thread اعمال می‌شود

Wrapper باید:

  • تابع execute را فراخوانی کند
  • نتیجهٔ آن را برگرداند
  • در صورت نیاز رفتار را تغییر دهد

۶. کاربردهای رایج Wrapperها

  • جلوگیری از اجرای کوئری در template (برای اطمینان از prefetch کامل)
  • اندازه‌گیری مدت زمان کوئری‌ها
  • ثبت کوئری‌ها برای تحلیل performance
  • شبیه‌سازی خطاهای دیتابیس
  • محدودکردن تعداد کوئری‌ها (مثلاً در تست‌ها)

جمع‌بندی

قابلیت execute_wrapper در Django ابزاری قدرتمند برای کنترل و تحلیل کوئری‌های دیتابیس است. با استفاده از wrapperها می‌توانید رفتار اجرای کوئری‌ها را تغییر دهید، آن‌ها را لاگ کنید، یا حتی اجرای آن‌ها را مسدود کنید. این ابزار برای بهینه‌سازی، تست، مانیتورینگ و جلوگیری از کوئری‌های ناخواسته بسیار مفید است.

نوشته و پژوهش‌شده توسط دکتر شاهین صیامی

مقالات مرتبط

فریم‌ورک Tasks در Django: راهنمای کامل اجرای کارهای پس‌زمینه در Django 6.0

Django 6.0 فریم‌ورک Tasks را معرفی کرده است؛ سیستمی داخلی برای تعریف و صف‌بندی کارهای پس‌زمینه خارج از چرخهٔ request–response. این مقاله نحوهٔ کار Tasks، پیکربندی backendها، تعریف و enqueue کردن Taskها، استفاده از context، و ادغام با سیستم‌های Worker خارجی را توضیح می‌دهد.

ادامه

پشتیبانی Asynchronous در Django: راهنمای کامل Async Views، ORM، Middleware، عملکرد و ایمنی

این مقاله پشتیبانی Django از برنامه‌نویسی غیرهم‌زمان (async) را توضیح می‌دهد. موضوعاتی مانند async views، اجرای Django تحت ASGI، رفتار middleware، قابلیت‌های ORM غیرهم‌زمان، sync_to_async، مدیریت قطع اتصال، نکات عملکردی، و مکانیزم‌های ایمنی Django برای جلوگیری از استفادهٔ ناامن async بررسی می‌شوند.

ادامه

System Check Framework در Django: راهنمای کامل نوشتن، ثبت، اجرا و تست چک‌های سیستمی

System Check Framework در Django مجموعه‌ای از بررسی‌های استاتیک برای تشخیص مشکلات رایج در پروژه است. این مقاله نحوهٔ اجرای چک‌ها، نوشتن چک‌های سفارشی، مدیریت پیام‌ها، برچسب‌گذاری چک‌ها، افزودن چک به مدل‌ها و فیلدها، و نوشتن تست‌های واحد و یکپارچه برای چک‌ها را توضیح می‌دهد.

ادامه

سیگنال‌ها در Django: راهنمای کامل استفاده، اتصال، ارسال و مدیریت Signalها

این مقاله سیستم سیگنال‌های Django را توضیح می‌دهد؛ مکانیزمی برای اطلاع‌رسانی رویدادها بین بخش‌های مختلف برنامه بدون ایجاد وابستگی مستقیم. موضوعاتی مانند نحوهٔ اتصال receiverها، استفاده از decorator، مدیریت senderهای خاص، محل مناسب قرارگیری کد سیگنال‌ها، هشدارهای مهم، و بهترین شیوه‌ها بررسی می‌شوند.

ادامه

آشنایی کامل با Django Settings: پیکربندی، مدیریت محیط، و بهترین شیوه‌ها

این مقاله یک راهنمای جامع دربارهٔ سیستم تنظیمات در Django ارائه می‌دهد. موضوعاتی مانند ساختار فایل تنظیمات، نحوهٔ تعیین DJANGO_SETTINGS_MODULE، استفاده از settings در کد، امنیت، پیکربندی دستی با configure()، استفادهٔ مستقل از Django با django.setup() و ایجاد تنظیمات سفارشی بررسی می‌شوند.

ادامه

سریال‌سازی و دسریال‌سازی در Django: راهنمای کامل کار با Serialization Framework

این مقاله سیستم سریال‌سازی Django را توضیح می‌دهد؛ از نحوهٔ تبدیل مدل‌ها به JSON، XML، YAML و JSONL گرفته تا دسریال‌سازی داده‌ها، سریال‌سازی فیلدهای انتخابی، کار با مدل‌های ارث‌بری، مدیریت روابط، و نکات مهم هنگام ذخیرهٔ داده‌های دسریال‌شده.

ادامه