# Dokumentasi Django 4.2.9.dev20231204082947

# Peralatan basisdata

Untuk membantu anda memahami dan mengendalikan permintaan dengan kode anda, Django menyediakan sebuah kaitan untuk memasang fungsi pembungkus disekitar penjalanan dari permintaan basisdata. Sebagai contoh, pembungkus dapat menghitung permintaan, mengukur lama permintaan, mencatat permintaan, atau bahkan mencegah penjalanan permintaan (sebagai contoh memastikan bahwa tidak ada permintaan diterbitkan selagi membangun cetakan dengan data pra pengambilan).

Pembungkus-pembungkus dimodelkan setelah middleware 1 -- mereka adalah callable yang mengambil callable lain sebagai argumen mereka. Mereka memanggil bahwa callable untuk meminta (kemungkinan dibungkus) permintaan basisdata, dan mereka dapat melakukan apa mereka ingin disekitaran panggilan itu. Mereka adalah, bagaimanapun, dibuat dan dipasang oleh kode pengguna, dan jadi tidak butuh memisahkan factory seperti middleware lakukan.

Memasang sebuah pembungkus selesai dalam sebuah pengelola konteks -- jadi pembungkus adalah sementara dan tertentu pada beberapa alur di kode anda.

Seperti disebutkan diatas, sebuah contoh dari sebuah pembungkus adalah penghadang penjalanan permintaan. Itu dapat terlihat seperti ini:

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

Dan itu akan digunakan dalam sebuah tampilan untuk menghadang permintaan dari cetakan seperti berikut:

    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)

Parameter dikirim ke pembungkus adalah:

- middleware 1 -- sebuah callable, yang harus diminta dengan sisa dari parameter untuk menjalankan permintaan.
- `sql` -- sebuah `str`, permintaan SQL dikirim ke basisdata.
- `params` -- sebuah list/tuple dari nilai-nilai parameter untuk perintah SQL, atau list/tuple dari list/tuple jika panggilan dibungkus adalah `executemany()`.
- `many` -- sebuah `bool` menunjukkan akhirnya panggilan dipangil adalah `execute()` atau `executemany()` (dan apakah `params` diharapkan menjadi berurut dari nilai-nilai, atau urutan dari urutan-urutan dari nilai-nilai).
- `context` -- sebuah dictionary dengan data lebih lanjut tentang konteks dari permohonan. Ini menyertakan hubungan dan kursor.

Menggunakan parameter, versi sedikit lebih rumit dari penghadang dapat menyertakan nama hubungan dalam pesan kesalahan:

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

Untuk contoh lebih lengkap, sebuah pencatat permintaan dapat terlihat seperti ini:

    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)

Untuk menggunakan ini, anda dapat membuat sebuah obyek pencatat dan memasang itu sebagai pembungkus:

    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)

Mengembalikan pengeola konteks yang, ketika dimasukkan, memasang sebuah pembungkus disekitar penjalanan permintaan basisdata, dan ketika keluar, memindahkan pembungkus. Pembungkus dipasang pada obyek hubungan lokal-thread.

`wrapper` adalah sebuah callable mengambil lima argumen. Itu dipanggil untuk setiap penjalanan permintaan dalam cakupan dari pengelola konteks, dengan argumen `execute`, `sql`, `params`, `many`, dan `context` sebagai digambarkan diatas. Itu diharapkan memanggil `execute(sql, params, many, context)` dan mengembalikan nilai balikan dari panggilan itu.