# Dokumentasi Django 5.2.8

# Basisdata

Django officially supports the following databases:

- PostgreSQL

- MariaDB

- MySQL

- Oracle

- SQLite

There are also a number of database backends provided by third parties.

Django berusaha mendukung sebanyak mungkin fitur-fitur pada semua backend basisdata. bagaimanapun, tidak semua backend basisdata sama, dan kami harus membuat perancangan keputusan pada dimana fitur-fitur untuk mendukung dan dimana anggapan kami dapat membuat aman.

This file describes some of the features that might be relevant to Django usage. It is not intended as a replacement for server-specific documentation or reference manuals.

## Catatan umum

### Hubungan tetap

Persistent connections avoid the overhead of reestablishing a connection to the database in each HTTP request. They're controlled by the `CONN_MAX_AGE` parameter which defines the maximum lifetime of a connection. It can be set independently for each database.

The default value is `0`, preserving the historical behavior of closing the database connection at the end of each request. To enable persistent connections, set `CONN_MAX_AGE` to a positive integer of seconds. For unlimited persistent connections, set it to `None`.

When using ASGI, persistent connections should be disabled. Instead, use your database backend's built-in connection pooling if available, or investigate a third-party connection pooling option if required.

#### Pengelolaan hubungan

Django membua sebuah hubungan pada basisdata ketika itu pertama kali membuat sebuah permintaan basisdata. Itu menjaga hubungan ini tetap terbuka dan menggunakan kembali itu dalam permintaan selanjutnya. Django menutup hubungan sekali itu melampau batas umur maksimal ditentukan oleh `CONN_MAX_AGE` atau ketika itu tidak digunakan lagi.

Secara terperinci, Django otomatis membuha sebuah hubungan pada basisdata kapanpun dia membutuhkan satu dan tidak mempunyai satu -- baik karena ini adalah hubungan pertama, atau karena hubungan sebelumnya telah ditutup.

Pada permulaan dari setiap permintaan, Django menutup hubungan jika itu telah mencapai umur maksimal. Jika basisdata anda memutuskan hubungan diam setelah beberapa waktu, anda harus menyetel `CONN_MAX_AGE` pada nilai terendah, sehingga Django tidak berusaha menggunakan hubungan yang telah diputus oleh peladen basisdata. (Masalah ini mungkin hanya berpengaruh situs lalu lintas sangat rendah.)

At the end of each request, Django closes the connection if it has reached its maximum age or if it is in an unrecoverable error state. If any database errors have occurred while processing the requests, Django checks whether the connection still works, and closes it if it doesn't. Thus, database errors affect at most one request per each application's worker thread; if the connection becomes unusable, the next request gets a fresh connection.

Setting `CONN_HEALTH_CHECKS` to `True` can be used to improve the robustness of connection reuse and prevent errors when a connection has been closed by the database server which is now ready to accept and serve new connections, e.g. after database server restart. The health check is performed only once per request and only if the database is being accessed during the handling of the request.

#### Peringatan

Sejak setiap thread merawat hubungan dia sendiri, basisdata anda harus mendukung setidaknya sebanyak hubungan serentak ketika anda memiliki thread pekerja.

Terkadang sebuah basisdata tidak mau diakses oleh kebanyakan dari tampilan anda, sebagai contoh karena itu adalah basisdata dari sebuah sistem luar, atau terima kasih ke penyimpanan sementara. Dalam kasus-kasus itu, anda harus mensetel `CONN_MAX_AGE` menjadi nilai rendah atau bahkan `0`, karena itu tidak masuk akal merawat sebuah hubungan untuk digunakan kembali. Ini akan membantu menjaga sejumlah hubungan serentak pada basisdata kecil ini.

Peladen pengembangan membuat sebuah thread baru untuk setiap permintaan dia tangani, meniadakan pengaruh dari hubungan tetap. Jangan mengadakan mereka selama pengembangan.

Ketika Django membangun sebuah hubungan ke basisdata, dia menyetel parameter yang sesuai, tergantung pada backend sedang digunakan. Jika anda mengadakan hubungan tetap, pengaturan ini tidak lagi berulang setiap permintaan. jika anda merubah parameter seperti tingkat pemisahan hubungan atau zona waktu, anda harus baik menyimpan kembali awalan Django pada akhir setiap permintaan, memaksa sebuah nilai sesuai pada permulaan dari setiap permintaan, atau meniadakan hubungan tetap.

If a connection is created in a long-running process, outside of Django’s request-response cycle, the connection will remain open until explicitly closed, or timeout occurs. You can use `django.db.close_old_connections()` to close all old or unusable connections.

### Penyandian

Django menganggap bahwa semua basisdata menggunakan penyandian UTF-8. Menggunakan penyandian lain mungkn menghasilkan perilaku tidak diharapkan seperti kesalahan "nilai terlalu panjang" dari basisdata anda untuk data yang sah dalam Django. Lihat basisdata catatan khusus dibawah untuk informasi pada bagaimana menyetel basisdata anda dengan benar.

## Catatan PostgreSQL

Django supports PostgreSQL 14 and higher. psycopg 3.1.12+ or psycopg2 2.9.9+ is required, though the latest psycopg 3.1.12+ is recommended.

Catatan

Support for `psycopg2` is likely to be deprecated and removed at some point in the future.

### Pengaturan hubungan PostgreSQL

Lihat `HOST` untuk rincian.

To connect using a service name from the connection service file and a password from the password file, you must specify them in the `OPTIONS` part of your database configuration in `DATABASES`:

`settings.py`

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            "OPTIONS": {
                "service": "my_service",
                "passfile": ".my_pgpass",
            },
        }
    }

`.pg_service.conf`

    [my_service]
    host=localhost
    user=USER
    dbname=NAME
    port=5432

`.my_pgpass`

    localhost:5432:NAME:USER:PASSWORD

The PostgreSQL backend passes the content of `OPTIONS` as keyword arguments to the connection constructor, allowing for more advanced control of driver behavior. All available parameters are described in detail in the PostgreSQL documentation.

Peringatan

Using a service name for testing purposes is not supported. This may be implemented later.

### Mengoptimalkan konfigurasi PostgreSQL

Django butuh parameter berikut untuk hubungan basisdatanya:

- `client_encoding`: `'UTF8'`,

- `default_transaction_isolation`: `'read committed'` secara awalan, atau nilai disetel dalam pilihan hubungan (lihat dibawah),

- `timezone`:

    - when `USE_TZ` is `True`, `'UTC'` by default, or the `TIME_ZONE` value set for the connection,

    - when `USE_TZ` is `False`, the value of the global `TIME_ZONE` setting.

Jika parameter ini sudah memiliki nilai benar, Django tidak akan mensetel mereka untuk setiap hubugan baru, yang which memperbaiki sedikit penampilan. Anda dapat menkonfigurasi mereka langsung dalam `postgresql.conf` atau lebih nyaman per pengguna basisdata ALTER ROLE.

Django akan bekerja baik tanpa optimalisasi ini, tetapi setiap hubungan baru akan melakukan beberapa permintaan untuk mensetel parameter ini.

### Tingkat terpencil

Seperti PostgreSQL itu sendiri, awalan Django pada `READ COMMITTED` isolation level. Jika anda butuh tingkat terpencil tertinggi seperti `REPEATABLE READ` atau `SERIALIZABLE`, setel itu dalam bagian `OPTIONS` dari konfigurasi basisdata anda dalam `DATABASES`:

    from django.db.backends.postgresql.psycopg_any import IsolationLevel

    DATABASES = {
        # ...
        "OPTIONS": {
            "isolation_level": IsolationLevel.SERIALIZABLE,
        },
    }

Catatan

Dibawah tingkat terpencil tertinggi, aplikasi anda harus dipersiapkan menangani pengecualian dimunculkan pada kegagalan serialisasi. Pilihan ini dirancang untuk pengguna lanjut.

### Peran

If you need to use a different role for database connections than the role used to establish the connection, set it in the `OPTIONS` part of your database configuration in `DATABASES`:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            # ...
            "OPTIONS": {
                "assume_role": "my_application_role",
            },
        },
    }

### Connection pool

To use a connection pool with psycopg, you can either set `"pool"` in the `OPTIONS` part of your database configuration in `DATABASES` to be a dict to be passed to `ConnectionPool`, or to `True` to use the `ConnectionPool` defaults:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            # ...
            "OPTIONS": {
                "pool": True,
            },
        },
    }

This option requires `psycopg[pool]` or psycopg-pool to be installed and is ignored with `psycopg2`.

### Server-side parameters binding

With psycopg 3.1.8+, Django defaults to the client-side binding cursors. If you want to use the server-side binding set it in the `OPTIONS` part of your database configuration in `DATABASES`:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.postgresql",
            # ...
            "OPTIONS": {
                "server_side_binding": True,
            },
        },
    }

This option is ignored with `psycopg2`.

### Indeks untuk kolom `varchar` dan `text`

When specifying `db_index=True` on your model fields, Django typically outputs a single `CREATE INDEX` statement. However, if the database type for the field is either `varchar` or `text` (e.g., used by `CharField`, `FileField`, and `TextField`), then Django will create an additional index that uses an appropriate PostgreSQL operator class for the column. The extra index is necessary to correctly perform lookups that use the `LIKE` operator in their SQL, as is done with the `contains` and `startswith` lookup types.

### Tindakan perpindahan untuk menambahkan tambahan.

Jika anda butuh menambahkan sebuah tambahan PostgreSQL (seperti `hstore`, `postgis`, dll.) menggunakan perpindahan, gunakan tindakan `CreateExtension`.

### Kursor sisi-peladen

When using `QuerySet.iterator()`, Django opens a server-side cursor. By default, PostgreSQL assumes that only the first 10% of the results of cursor queries will be fetched. The query planner spends less time planning the query and starts returning results faster, but this could diminish performance if more than 10% of the results are retrieved. PostgreSQL's assumptions on the number of rows retrieved for a cursor query is controlled with the cursor_tuple_fraction option.

#### Menggabungkan transaksi dan kursor sisi-peladen

Using a connection pooler in transaction pooling mode (e.g. PgBouncer) requires disabling server-side cursors for that connection.

Kursos sisi-peladen adalah lokal terhadap sebuah hubungan dan tetap terbuka pada akhir dari sebuah transaksi ketika `AUTOCOMMIT` adalah `True`. Sebuah transaksi seanjutnya mungkin berusaha mengambil hasil lebih dari kursor sisi-peladen. Dalam suasana pengumpulan transaksi, tidak ada jaminan bahwa transaksi sebelumnya akan menggunakan hubungan sama. Jika sebuah hubungan berbeda digunakan, sebuah kesalahan dimunculkan ketika transaksi mengacu kursor sisi-peladen, karena kursos sisi-peladen hanya tersedia dalam hubungan dimana mereka dibuat.

Satu pemecahan adalah untuk meniadakan kursor sisi peladen untuk sebuah hubungan adalah `DATABASES` by setting `DISABLE_SERVER_SIDE_CURSORS` menjadi `True`.

Keuntungan dari kursor sisi-peladen dalam suasana penggabungan transaksi, anda dapat menyetel another connection to the database untuk melakukan permintaan yang menggunakan kursor sisi-peladen. Hubungan ini butuh salah satu langsung ke basisdata atau ke hubungan pengumpulan dalam suasana sesi pengumpulan.

Pilihan lain adalah membungkus setiap `QuerySet` menggunakan kursor sisi-peladen dalam sebuah blok `atomic()`, karena itu meniadakan `autocommit` untuk lamanya transaksi. Cara ini, kursor sisi-peladen akan hanya tinggal untuk selama transaksi.

### Manual-menentukan nilai-nilai dari primary key peningkatan-otomatis

Django uses PostgreSQL's identity columns to store auto-incrementing primary keys. An identity column is populated with values from a sequence that keeps track of the next available value. Manually assigning a value to an auto-incrementing field doesn't update the field's sequence, which might later cause a conflict. For example:

    >>> from django.contrib.auth.models import User
    >>> User.objects.create(username="alice", pk=1)
    <User: alice>
    >>> # The sequence hasn't been updated; its next value is 1.
    >>> User.objects.create(username="bob")
    IntegrityError: duplicate key value violates unique constraint
    "auth_user_pkey" DETAIL:  Key (id)=(1) already exists.

If you need to specify such values, reset the sequence afterward to avoid reusing a value that's already in the table. The `sqlsequencereset` management command generates the SQL statements to do that.

### Cetakan percobaan basisdata

Anda dapat menggunakan pengaturan `TEST['TEMPLATE']` untuk menentukan template (misalnya `'template0'`) dari mana membuat basis data percobaan.

### Mempercepat penjalanan percobaan dengan pengaturan tidak-tahan-lama

Anda dapat mempercepat waktu penjalanan percobaan dengan configuring PostgreSQL to be non-durable.

Peringatan

Ini sangat berbahaya: itu akan membuat basisdata anda lebih rentan terhadap kehilangan data atau korupsi dalam kasus dari peladen roboh atau kehilangan daya. Gunakan ini hanya pada mesin pengembangan dimana anda dapat dengan mudah menyimpan kembali seluruh isi dari semua basisdata dalam gugus.

## MariaDB notes

Django supports MariaDB 10.6 and higher.

To use MariaDB, use the MySQL backend, which is shared between the two. See the MySQL notes for more details.

## Catatan MySQL

### Versi dukungan

Django supports MySQL 8.0.11 and higher.

Fitur `inspectdb` Django menggunakan basisdata `information_schema`, yang mengandung rincian data pada semua skema basisdata.

Django mengharapkan basisdata untuk mendukung Unicode (UTF-8 encoding) dan menugaskan ke itu tugas dari memaksa transaksi dan keutuhan referensial. itu adalah penting untuk waspada dari fakta bahwa dua terakhir sebenarnya tidak dipaksa oleh MySQL ketika menggunakan mesin penyimpanan, lihat bagian selanjutnya.

### Mesin penyimpanan

MySQL mempunyai beberapa storage engines. Anda dapat merubah mesin penyimpanan awalan dalam konfigurasi peladen.

Mesin penyimpanan awalan MySQL adalah InnoDB. Mesin ini sepenuhnya transaksional dan mendukung acuan foreign key. Itu adalah pilihan dianjurkan. Bagaimanapun penghitung peningkatan otomatis InnoDB hilang pada pemulaian kembali MySQL karena itu tidak ingat nilai `AUTO_INCREMENT`, daripada membuat kembali itu sebagai "max(id)+1". Ini mungkin menghasilkan sebuah penggunaan kembali tidak sengaja dari nilai `AutoField`.

Kekurangan utama dari MyISAM adalah bahwa itu tidak mendukung transaksi atau memaksa batasan foreign-key.

### Driver API DB MySQL

MySQL mempunyai sepasang driver yang menerapkan API Basisdata Python digambarkan dalam PEP 249:

- mysqlclient is a native driver. It's the recommended choice.

- MySQL Connector/Python adalah murni pengemudi Python dari Oracle yang tidak mewajibkan pustaka klien MySQL atau modul Python apapun diluar dari pustaka standar.

Sebagai tambahan pada pengemudi API DB, Django butuh sebuah penyadur mengakses pengemudi basisdata dari ORM nya. Django menyediakan sebuah penyadur untuk mysqlclient selagi Penghubung/Python MySQL termasuk its own.

#### mysqlclient

Django requires mysqlclient 2.2.1 or later.

#### Penghubung MySQL/Python

Penghubung/Python MySQL tersedia dari download page. Penyadur Django tersedia dalam versi 1.1.X dan terakhir. itu mungkin tidak mendukung kebanyakan terbitan terakhir dari Django.

### Pengertian zona waktu

Jika anda berencana menggunakan dukungan timezone Django, gunakan mysql_tzinfo_to_sql untuk memuat tabel zona waktu kedalam basisdata MySQL. Ini harus dilakukan hanya sekali untuk peladen MySQL anda, bukan per basisdata.

### Membuat basisdata anda

You can create your database using the command-line tools and this SQL:

    CREATE DATABASE <dbname> CHARACTER SET utf8mb4;

Ini memastikan semua tabel dan kolom akan menggunakan UTF-8 secara awal.

#### Pengaturan pemeriksaan

The collation setting for a column controls the order in which data is sorted as well as what strings compare as equal. You can specify the `db_collation` parameter to set the collation name of the column for `CharField` and `TextField`.

The collation can also be set on a database-wide level and per-table. This is documented thoroughly in the MySQL documentation. In such cases, you must set the collation by directly manipulating the database settings or tables. Django doesn't provide an API to change them.

By default, with a UTF-8 database, MySQL will use the `utf8mb4_0900_ai_ci` collation. This results in all string equality comparisons being done in a case-insensitive manner. That is, `"Fred"` and `"freD"` are considered equal at the database level. If you have a unique constraint on a field, it would be illegal to try to insert both `"aa"` and `"AA"` into the same column, since they compare as equal (and, hence, non-unique) with the default collation. If you want case-sensitive comparisons on a particular column or table, change the column or table to use the `utf8mb4_0900_as_cs` collation.

Please note that according to MySQL Unicode Character Sets, comparisons for the `utf8mb4_general_ci` collation are faster, but slightly less correct, than comparisons for `utf8mb4_unicode_ci`. If this is acceptable for your application, you should use `utf8mb4_general_ci` because it is faster. If this is not acceptable (for example, if you require German dictionary order), use `utf8mb4_unicode_ci` because it is more accurate.

Peringatan

Model formsets validate unique fields in a case-sensitive manner. Thus when using a case-insensitive collation, a formset with unique field values that differ only by case will pass validation, but upon calling `save()`, an `IntegrityError` will be raised.

### Menyambung ke basisdata

Mengacu ke pengaturan dokumentasi.

Pengaturan hubungan digunakan dalam urutan ini:

1. `OPTIONS`.

2. `NAME`, `USER`, `PASSWORD`, `HOST`, `PORT`

3. Berkas pilihan MySQL.

Dengan kata lain, jika anda mensetel nama dari basisdata dalam `OPTIONS`, ini akan mengambil hak lebih tinggi terhadap `NAME`, yang akan menimpa apapin dalam MySQL option file.

Ini adalah contoh konfigurasi yang menggunakan berkas pilihan MySQL:

    # settings.py
    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.mysql",
            "OPTIONS": {
                "read_default_file": "/path/to/my.cnf",
            },
        }
    }

    # my.cnf
    [client]
    database = NAME
    user = USER
    password = PASSWORD
    default-character-set = utf8mb4

Beberapa MySQLdb connection options lain mungkin berguna, seperti `ssl`, `init_command`, dan `sql_mode`.

#### Mengatur `sql_mode`

The default value of the `sql_mode` option contains `STRICT_TRANS_TABLES`. That option escalates warnings into errors when data are truncated upon insertion, so Django highly recommends activating a strict mode for MySQL to prevent data loss (either `STRICT_TRANS_TABLES` or `STRICT_ALL_TABLES`).

Jika anda butuh menyesuaiakan suasana SQL, anda dapat mensetel variabel `sql_mode` seperti pilihan MySQL lain: antara dalam berkas konfigurasi atau dengan masukan `'init_command': "SET sql_mode='STRICT_TRANS_TABLES'"` dalam bagian `OPTIONS` dari konfigurasi basisdata anda dalam `DATABASES`.

#### Tingkat terpencil

Ketika menjalankan pemuatan yang bersamaan, transaksi basisdata dari sesi-sesi berbeda (katakan, urutan lain menangani permintaan berbeda) mungkin berinteraksi dengan satu sama lain. Interaksi ini mungkin dipengaruhi oleh setiap transaction isolation level sesi. Anda dapat mensetel tingkat terpencil hubungan dengan sebuah masukan `'isolation_level'` dalam `OPTIONS` bagian dari konfigurasi basisdata anda dalam `DATABASES`. Nilai sah untuk masukan ini adalah empat sandar tingkat terpencil:

- `'read uncommitted'`

- `'read committed'`

- `'repeatable read'`

- `'serializable'`

or `None` to use the server's configured isolation level. However, Django works best with and defaults to read committed rather than MySQL's default, repeatable read. Data loss is possible with repeatable read. In particular, you may see cases where `get_or_create()` will raise an `IntegrityError` but the object won't appear in a subsequent `get()` call.

### Membuat tabel anda

Ketika Django membangkitkan skema, itu tidak menentukan sebuah mesin penyimpanan, jadi tabel-tabel akan dibuat dengan apapun mesin penyimpanan awalan paladen basisdata anda dikonfigurasikan. Pemecahan paling mudah adalah mensetel mesin penyimpanan awalan peladen basisdata anda pada mesin yang diinginkan.

Jika anda sedang menggunakan layanan rumahan dan tidak dapat merubah mesin penyimpanan awalan peladen, anda memiliki sepasang pilihan.

- After the tables are created, execute an `ALTER TABLE` statement to convert a table to a new storage engine (such as InnoDB):

      ALTER TABLE <tablename> ENGINE=INNODB;

  Ini dapat membosankan jika anda memiliki banyak tabel.

- Pilihan lain adalah menggunakan pilihan `init_command` untuk MySQLdb sebelum membuat tabel anda:

      "OPTIONS": {
          "init_command": "SET default_storage_engine=INNODB",
      }

  Ini menyetel mesin penyimpanan awalan diatas hubungan ke basisdata. Setelah tabel-tabel anda telah dibuat, anda harus memindahkan pilihan ini ketika itu menambahkan sebuah permintaan yaitu hanya dibutuhkan selama pembautan tabel pada setiap hubungan basisdata.

### Nama tabel

Ada known issues di bahkan versi terakhir dari MySQL yang dapat menyebabkan kasus dari nama tabel dirubah ketika pernyataan SQL tertentu dijalankan dibawah kondisi tertentu. Itu dianjurkan bahwa anda menggunakan nama tabel huruf kecil, jika memungkinkan, untuk menghindari masalah apapun yang mungkin muncul dari perilaku ini. Django menggunakan nama tabel huruf kecil ketika it membangkitkan-otomatis nama tabel dari mdoel, jadi ini adalah pertimbangan utama jika anda sedang menimpa nama tabel melalui parameter `db_table`.

### Savepoint

Kedua ORM Django dan MySQL (ketika menggunakan InnoDB storage engine) mendukung basisdata savepoints.

If you use the MyISAM storage engine please be aware of the fact that you will receive database-generated errors if you try to use the savepoint-related methods of the transactions API. The reason for this is that detecting the storage engine of a MySQL database/table is an expensive operation so it was decided it isn't worth to dynamically convert these methods in no-op's based in the results of such detection.

### Catatan pada tabel khusus

#### Bidang karakter

Any fields that are stored with `VARCHAR` column types may have their `max_length` restricted to 255 characters if you are using `unique=True` for the field. This affects `CharField`, `SlugField`. See the MySQL documentation for more details.

#### Batasan `TextField`

MySQL hanya dapat mengindeks karakter N pertama dari kolom `BLOB` atau `TEXT`. Sejak `TextField` tidak memiliki panjang yang ditentukan, anda tidak dapat menanda itu sebagai `unique=True`. MySQLakan melaporkan: "kolom BLOB/TEXT '<db_column>' digunakan dalam spesifikasi kunci tanpa panjang kunci".

#### Pecahan kedua mendukung untuk bidang Time dan DateTime

MySQL can store fractional seconds, provided that the column definition includes a fractional indication (e.g. `DATETIME(6)`).

Django will not upgrade existing columns to include fractional seconds if the database server supports it. If you want to enable them on an existing database, it's up to you to either manually update the column on the target database, by executing a command like:

    ALTER TABLE `your_table` MODIFY `your_datetime_column` DATETIME(6)

atau menggunakan tindakan `RunSQL` dalam data migration.

#### Kolom `TIMESTAMP`

Jika anda menggunakan sebuah basisdata warisan yang mengandung kolom `TIMESTAMP`, anda harus mensetel `USE_TZ = False` untuk menghindari kerusakan data. `inspectdb` memetakan kolom-kolom ini pada `DateTimeField` dan jika anda mengadakan dukungan zona waktu, kedua MySQL dan Django akan berusaha merubah nilai-nilai dari UTC ke waktu lokal.

### Penguncian baris dengan `QuerySet.select_for_update()`

MySQL and MariaDB do not support some options to the `SELECT ... FOR UPDATE` statement. If `select_for_update()` is used with an unsupported option, then a `NotSupportedError` is raised.

Option | MariaDB | MySQL
--- | --- | ---
`SKIP LOCKED` | X | X
`NOWAIT` | X | X
`OF` |  | X
`NO KEY` |  |

When using `select_for_update()` on MySQL, make sure you filter a queryset against at least a set of fields contained in unique constraints or only against fields covered by indexes. Otherwise, an exclusive write lock will be acquired over the full table for the duration of the transaction.

### Typecasting otomatis dapat menggunakan hasil tidak diharapkan

Ketika melakukan sebuah permintaan pada jenis string, tetapi dengan sebuah nilai integer, MySQL akan memaksa jenis-jenis dari semua nilai dalam tabel pada sebuah integer sebelum melakukan perbandingan. Jika tabel-tabel anda mengandung nilai `'abc'`, `'def'` dan permintaan anda untuk `WHERE mycolumn=0`, kedua baris akan cocok. Mirip, `WHERE mycolumn=1` akan cocok nilai `'abc1'`. Karena itu, bidang-bidang jenis string disertakan dalam Django akan selalu melempar nilai ke sebuah string sebelum menggunakan itu dalam sebuah permintaan.

Jika anda menerapkan bdiang model penyesuaian yang mewarisi dari `Field` directly, adalah menimpa `get_prep_value()`, atau menggunakan `RawSQL`, `extra()`, atau `raw()`, anda harus memastikan bahwa anda melakukan typecasting yang sesuai.

## Catatan SQLite

Django supports SQLite 3.31.0 and later.

SQLite menyediakan cara lain pengembangan yang bagus untuk aplikasi-aplikasi yang terutama hanya-baca atau membutuhkan jejak kaki pemasangan terkecil. Seperti semua peladen basisdata, meskipun, ada beberapa perbendaan yang khusus pada SQLite yang anda harus waspadai.

### Substring matching and case sensitivity

For all SQLite versions, there is some slightly counterintuitive behavior when attempting to match some types of strings. These are triggered when using the `iexact` or `contains` filters in querysets. The behavior splits into two cases:

1. For substring matching, all matches are done case-insensitively. That is a filter such as `filter(name__contains="aa")` will match a name of `"Aabb"`.

2. For strings containing characters outside the ASCII range, all exact string matches are performed case-sensitively, even when the case-insensitive options are passed into the query. So the `iexact` filter will behave exactly the same as the `exact` filter in these cases.

Some possible workarounds for this are documented at sqlite.org, but they aren't utilized by the default SQLite backend in Django, as incorporating them would be fairly difficult to do robustly. Thus, Django exposes the default SQLite behavior and you should be aware of this when doing case-insensitive or substring filtering.

### Decimal handling

SQLite has no real decimal internal type. Decimal values are internally converted to the `REAL` data type (8-byte IEEE floating point number), as explained in the SQLite datatypes documentation, so they don't support correctly-rounded decimal floating point arithmetic.

### Kesalahan "Basisdata terkunci"

SQLite berarti menjadi basisdata ringan, dan demikian tidak dapat mendukung bersamaan tingkat tinggi. Kesalahan `OperationalError: bassidata dikunci` menunjukkan bahwa aplikasi anda berpengalaman lebih bersamaan daripada `sqlite` dapat tangani dalam konfigurasi awalan. Kesalahan ini berarti bahwa satu antrian atau proses mempunyai sebuah kunci khusus pada hubungan basisdata dan waktu habis antrian lain menunggu untuk kunci dibebaskan.

Pembungkus SQLite Python mempunyai nilai waktu habis awalan yang menentukan seberapa lama detik urutan diizinkan untuk menunggu penguncian sebelum itu berakhir dan memunculkan kesalahan `OperationalError: database is locked`.

Jika anda mendapatkan kesalahan ini, anda dapat menyelesaikannya dengan:

- Berganti ke backend basisdata lain. Pada titik tertentu SQLite menjadi terlalu "ringan" untuk aplikasi dunia-sebenarnya, dan urutan kesalahan bersamaan ini menunjukkan anda telah mencapat titik itu.

- Menulis kembali kode anda untuk mengurangi bersamaan dan memastikan transaksi basisdata adalah berumur-pendek.

- Meningkatkan nilai waktu habis awalan dengan mengatur pilihan basisdata `timeout`:

      "OPTIONS": {
          # ...
          "timeout": 20,
          # ...
      }

  This will make SQLite wait a bit longer before throwing "database is locked" errors; it won't really do anything to solve them.

#### Transactions behavior

SQLite supports three transaction modes: `DEFERRED`, `IMMEDIATE`, and `EXCLUSIVE`.

The default is `DEFERRED`. If you need to use a different mode, set it in the `OPTIONS` part of your database configuration in `DATABASES`, for example:

    "OPTIONS": {
        # ...
        "transaction_mode": "IMMEDIATE",
        # ...
    }

To make sure your transactions wait until `timeout` before raising "Database is Locked", change the transaction mode to `IMMEDIATE`.

For the best performance with `IMMEDIATE` and `EXCLUSIVE`, transactions should be as short as possible. This might be hard to guarantee for all of your views so the usage of `ATOMIC_REQUESTS` is discouraged in this case.

For more information see Transactions in SQLite.

### `QuerySet.select_for_update()` tidak didukung

SQLite tidak mendukung sintaksis `SELECT ... FOR UPDATE`. Memanggil itu tidak akan memiliki pengaruh.

### Pengucilan ketika menggunakan `QuerySet.iterator()`

There are special considerations described in Isolation In SQLite when modifying a table while iterating over it using `QuerySet.iterator()`. If a row is added, changed, or deleted within the loop, then that row may or may not appear, or may appear twice, in subsequent results fetched from the iterator. Your code must handle this.

### Enabling JSON1 extension on SQLite

To use `JSONField` on SQLite, you need to enable the JSON1 extension on Python's `sqlite3` library. If the extension is not enabled on your installation, a system error (`fields.E180`) will be raised.

To enable the JSON1 extension you can follow the instruction on the wiki page.

Catatan

The JSON1 extension is enabled by default on SQLite 3.38+.

### Setting pragma options

Pragma options can be set upon connection by using the `init_command` in the `OPTIONS` part of your database configuration in `DATABASES`. The example below shows how to enable extra durability of synchronous writes and change the `cache_size`:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.sqlite3",
            # ...
            "OPTIONS": {
                "init_command": "PRAGMA synchronous=3; PRAGMA cache_size=2000;",
            },
        }
    }

## Catatan Oracle

Django supports Oracle Database Server versions 19c and higher. Version 2.3.0 or higher of the oracledb Python driver is required.

Untuk perintah `python manage.py migrate` bekerja, pengguna basisdata Oracle anda harus mempunyai hak istimewa untuk menjalankan perintah berikut:

- CREATE TABLE

- CREATE SEQUENCE

- CREATE PROCEDURE

- CREATE TRIGGER

Untuk menjalankan deretan percobaan proyek, pengguna biasanya butuh hak tambahan ini:

- CREATE USER

- ALTER USER

- DROP USER

- CREATE TABLESPACE

- DROP TABLESPACE

- CREATE SESSION WITH ADMIN OPTION

- CREATE TABLE WITH ADMIN OPTION

- CREATE SEQUENCE WITH ADMIN OPTION

- CREATE PROCEDURE WITH ADMIN OPTION

- CREATE TRIGGER WITH ADMIN OPTION

Selagi peran `RESOURCE` mempunyai hak istimewa yang diwajibkan `CREATE TABLE`, `CREATE SEQUENCE`, `CREATE PROCEDURE`, dan `CREATE TRIGGER`, dan seorang pengguna diberikan ``RESOURCE WITH ADMIN OPTION` dapat memberikan `RESOURCE`, pengguna seperti itu tidak dapat memberikan hak istimewa sendiri (yaitu `CREATE TABLE`), dan demikian `RESOURCE WITH ADMIN OPTION` tidak biasanya cukup untuk menjalankan percobaan.

Some test suites also create views or materialized views; to run these, the user also needs `CREATE VIEW WITH ADMIN OPTION` and `CREATE MATERIALIZED VIEW WITH ADMIN OPTION` privileges. In particular, this is needed for Django's own test suite.

Semua hak iswimewa ini disertakan dalam peran DBA, yang sesuai untuk digunakan pada basisdata pengembang pribadi.

Backend basisdata Oracle menggunakan paket `SYS.DBMS_LOB` dan `SYS.DBMS_RANDOM`, jadi pengguna anda akan membutuhkan menjalankan perizinan padanya. Itu secara biasa dapat diakses ke semua pengguna secara awal, tetapi di kasus itu tidak, anda akan butuh memberikan perizinan seperti itu:

    GRANT EXECUTE ON SYS.DBMS_LOB TO user;
    GRANT EXECUTE ON SYS.DBMS_RANDOM TO user;

### Menyambung ke basisdata

Untuk menghubungkan menggunakan nama layanan dari basisdata Oracle anda, berkas `settings.py` anda harus terlihat seperti ini:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.oracle",
            "NAME": "xe",
            "USER": "a_user",
            "PASSWORD": "a_password",
            "HOST": "",
            "PORT": "",
        }
    }

Dalam kasus ini, anda harus meninggakan kedua `HOST` dan `PORT` kosong. Bagaimanapun, jika anda tidak menggunakan berkas `tnsnames.ora` atau metode penamaan mirip dan ingin berhubungan menggunakan SID ("xe" dalam contoh ini), kemudian isi kedua `HOST` dan `PORT` seperti itu:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.oracle",
            "NAME": "xe",
            "USER": "a_user",
            "PASSWORD": "a_password",
            "HOST": "dbprod01ned.mycompany.com",
            "PORT": "1540",
        }
    }

Anda harus salah andara mendukung kedua `HOST` and `PORT`, atau meninggalkan kedua sebagai string kosong. Django akan menggunakan deskriptor hubungan berbeda tergantung pada pilihan itu.

#### DSN dan Easy Connect penuh

Sebuah Full DSN atau string Easy Connect dapat digunakan dalam `NAME` jika kedua `HOST` dan `PORT` adalah kosong. Bentuk ini diwajibkan ketika menggunakan RAC atau basisdata tertanam tanpa `tnsnames.ora`, sebagai contoh.

Contoh dari Easy Connect string:

    "NAME": "localhost:1521/orclpdb1"

Contoh dari string DSN penuh:

    "NAME": (
        "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))"
        "(CONNECT_DATA=(SERVICE_NAME=orclpdb1)))"
    )

### Connection pool

New in Django 5.2.

To use a connection pool with oracledb, set `"pool"` to `True` in the `OPTIONS` part of your database configuration. This uses the driver's create_pool() default values:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.oracle",
            # ...
            "OPTIONS": {
                "pool": True,
            },
        },
    }

To pass custom parameters to the driver's create_pool() function, you can alternatively set `"pool"` to be a dict:

    DATABASES = {
        "default": {
            "ENGINE": "django.db.backends.oracle",
            # ...
            "OPTIONS": {
                "pool": {
                    "min": 1,
                    "max": 10,
                    # ...
                }
            },
        },
    }

### INSERT ... RETURNING INTO

By default, the Oracle backend uses a `RETURNING INTO` clause to efficiently retrieve the value of an `AutoField` when inserting new rows. This behavior may result in a `DatabaseError` in certain unusual setups, such as when inserting into a remote table, or into a view with an `INSTEAD OF` trigger. The `RETURNING INTO` clause can be disabled by setting the `use_returning_into` option of the database configuration to `False`:

    "OPTIONS": {
        "use_returning_into": False,
    }

Dalam kasus ini, backend Oracle akan menggunakan permintaan `SELECT` terpisah untuk mengambil nilai-nilai `AutoField`.

### Masalah penamaan

Oracle memaksakan batasan panjang nama dari 30 karakter. Untuk mengakomodasi ini, backend memotong penciri basisdata agar cocok, mengganti empat karakter akhir dari nama terpotong dengan sebuah nilai campuran MD5 berulang. Sebagai tambahan, backend merubah penciri basisdata menjadi semua-huruf-besar.

Untuk mencegah perubahan ini (ini biasanya hanya membutuhkan ketika berhubungan dengan basisdata warisan atau mengakses tabel-tabel yang milik pengguna lain), gunakan sebuah nama terkutip sebagai nilai untuk `db_table`:

    class LegacyModel(models.Model):
        class Meta:
            db_table = '"name_left_in_lowercase"'

    class ForeignModel(models.Model):
        class Meta:
            db_table = '"OTHER_USER"."NAME_ONLY_SEEMS_OVER_30"'

Nama terkutip dapat juga digunakan dengan backend basisdata didukung lain Django; kecuali untuk Oracle, bagaimanapun, kutipan tidak mempunyai pengaruh.

When running `migrate`, an `ORA-06552` error may be encountered if certain Oracle keywords are used as the name of a model field or the value of a `db_column` option. Django quotes all identifiers used in queries to prevent most such problems, but this error can still occur when an Oracle datatype is used as a column name. In particular, take care to avoid using the names `date`, `timestamp`, `number` or `float` as a field name.

### String NULL dan kosong

Django umumnya memilih menggunakan string kosong (`''`) daripada `NULL`, tetapi Oracle memperlakukan keduanya mirip. Untuk menyiasati ini, backend Oracle mengabaikan pilihan `null` tersirat pada bidang yang mempunyai string kosong sebagai nilai kemungkinan dan membangkitkan DDL seolah-olah `null=True`. Ketika mengambil dari basisdata, itu dianggap bahwa sebuah nilai `NULL` dalam satu dari bidang-bidang ini sangat berarti string kosong, dan data secara diam dirubah untuk mencerminkan anggapan ini.

### Batasan `TextField`

The Oracle backend stores each `TextField` as an `NCLOB` column. Oracle imposes some limitations on the usage of such LOB columns in general:

- Kolom LOB tidak boleh digunakan sebagai primary key.

- Kolom LOB tidak boleh digunakan sebagai indeks.

- Kolom LOB mugnkin tidak digunakan dalam daftar `SELECT DISTINCT`. Ini berarti bahwa mencoba menggunakan metode `QuerySet.distinct` pada sebuah model yang menyertakan kolom `TextField` akan menghasilkan dalam sebuah kesalahan `ORA-00932` ketika berjalan terhadap Oracle. Sebagai pemecahannya, gunakan metode `QuerySet.defer` dalam berhubungan dengan `distinct()` untuk mencegah kolom `TextField` dari menjadi disertakan dalam daftar `SELECT DISTINCT`.

## Subclassing the built-in database backends

Django comes with built-in database backends. You may subclass an existing database backend to modify its behavior, features, or configuration.

Consider, for example, that you need to change a single database feature. First, you have to create a new directory with a `base` module in it. For example:

    mysite/
        ...
        mydbengine/
            __init__.py
            base.py

The `base.py` module must contain a class named `DatabaseWrapper` that subclasses an existing engine from the `django.db.backends` module. Here's an example of subclassing the PostgreSQL engine to change a feature class `allows_group_by_selected_pks_on_model`:

`mysite/mydbengine/base.py`

    from django.db.backends.postgresql import base, features

    class DatabaseFeatures(features.DatabaseFeatures):
        def allows_group_by_selected_pks_on_model(self, model):
            return True

    class DatabaseWrapper(base.DatabaseWrapper):
        features_class = DatabaseFeatures

Akhirnya, anda harus menentukan `DATABASE-ENGINE`di berkas ``settings.py`` anda:

    DATABASES = {
        "default": {
            "ENGINE": "mydbengine",
            # ...
        },
    }

You can see the current list of database engines by looking in django/db/backends.

## Menggunakan backend basisdata pihak ketiga

Sebagai tambahan pada basisdata didukung resmi, ada backend disediakan oleh pihak ketiga yang mengizinkan anda menggunakan basisdata lain dengan Django:

- CockroachDB

- Firebird

- Google Cloud Spanner

- Microsoft SQL Server

- MongoDB

- Snowflake

- TiDB

- YugabyteDB

Versi Django dan fitur ORM didukung oleh backend tidak resmi sangat beragam. Permintaan mengenai kemampuan khusus dari backend tidak resmi ini, bersama dengan permintaan didukung apapun, harus diarahkan ke saluran pendukung disediakan oleh proyek pihak ke3.