Opsi koneksi untuk mssql-django

Artikel ini menjelaskan pengaturan kamus OPTIONS dalam konfigurasi Django DATABASES Anda. Pengaturan ini mengontrol cara mssql-django menyambungkan ke SQL Server melalui driver ODBC.

Pemilihan driver ODBC

Mulai versi mssql-django 1.7, backend menggunakan ODBC Driver 18 for SQL Server secara default. Jika ODBC Driver 18 tidak diinstal, backend secara otomatis kembali ke ODBC Driver 17.

Note

Odbc Driver 18 diaktifkan Encrypt=yes secara default dan memvalidasi sertifikat server. Koneksi yang bekerja dengan Driver 17 dapat gagal dengan kesalahan kepercayaan SSL/TLS. Untuk mengatasi kegagalan:

  • Untuk SQL Server lokal, instal sertifikat server dari otoritas sertifikat yang sudah dipercaya klien Anda, atau impor sertifikat server yang ada ke setiap penyimpanan kepercayaan klien. Untuk petunjuknya, lihat Mengonfigurasi Mesin Database SQL Server untuk mengenkripsi koneksi.
  • Jika Anda terhubung dengan alamat IP atau dengan alias yang tidak cocok dengan subjek sertifikat atau nama alternatif subjek (SAN), tambahkan HostNameInCertificate=<name-from-certificate> ke extra_params.

Untuk pengembangan lokal terhadap sertifikat yang ditandatangani sendiri, lihat TrustServerCertificate di Parameter ODBC Tambahan.

Anda dapat menentukan driver secara eksplisit:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 17 for SQL Server",
        },
    },
}

Di Linux, Anda juga dapat menentukan jalur lengkap ke pustaka driver:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "/opt/microsoft/msodbcsql18/lib64/libmsodbcsql-18.0.so.1.1",
        },
    },
}

DSN vs HOST

Anda dapat terhubung menggunakan nama HOST atau DSN (Data Source Name) yang diberi nama.

Hubungkan ke HOST

Sebagian besar konfigurasi langsung menggunakan setelan HOST:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Hubungkan ke DSN

Gunakan DSN bernama yang dikonfigurasi di sumber data ODBC Anda:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "OPTIONS": {
            "dsn": "MyDataSourceName",
        },
    },
}

Dukungan FreeTDS

Untuk menggunakan FreeTDS sebagai driver ODBC, atur host_is_server ke True. Ini memberi tahu backend agar menggunakan HOST dan PORT secara langsung alih-alih mencari nama dataserver di freetds.conf:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "FreeTDS",
            "host_is_server": True,
        },
    },
}

Untuk informasi selengkapnya tentang koneksi tanpa DSN dengan FreeTDS, lihat Panduan pengguna FreeTDS.

Parameter ODBC tambahan

Gunakan extra_params untuk meneruskan parameter string koneksi ODBC tambahan. Nilainya adalah string yang dipisahkan dengan titik koma yang ditambahkan ke string koneksi:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>.database.windows.net",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "TrustServerCertificate=yes;ApplicationIntent=ReadOnly",
        },
    },
}

Pengaturan ini juga digunakan untuk kata kunci autentikasi Microsoft Entra.

Saat menyambungkan ke Azure SQL Database, Azure SQL Managed Instance, database SQL di Microsoft Fabric, listener grup ketersediaan, atau instans kluster failover, tambahkan MultiSubnetFailover=Yes ke extra_params. Ketika nama server diuraikan menjadi lebih dari satu alamat IP, driver terhubung ke semua alamat tersebut secara bersamaan dan menggunakan alamat pertama yang merespons. Tanpa itu, pengemudi mencoba alamat satu per satu, dan alamat yang tidak menjawab menghabiskan sisa waktu otentikasi sebelum pengemudi beralih ke alamat berikutnya. Ketika DNS mengarah ke satu alamat, driver hanya melakukan satu upaya koneksi, jadi pengaturan ini aman jika dibiarkan aktif.

MultiSubnetFailover=Yes memiliki batasan sebagai berikut:

  • Anda tidak bisa menggunakannya di atas protokol selain TCP.

  • Menghubungkan ke instance SQL Server yang dikonfigurasi dengan lebih dari 64 alamat IP gagal.

  • Anda tidak bisa menggunakannya dengan pencerminan database. Driver mengembalikan kesalahan ketika string koneksi menyebutkan Failover_Partner, serta ketika server melaporkan bahwa basis data dicerminkan. Pencerminan basis data sudah tidak digunakan lagi di semua versi SQL Server yang didukung. Gunakan grup ketersediaan AlwaysOn sebagai gantinya.

Perhatian

Gunakan TrustServerCertificate=yes hanya untuk pengembangan lokal dengan sertifikat yang ditandatangani sendiri. Jangan gunakan dalam produksi. Ini menonaktifkan validasi rantai sertifikat dan meningkatkan risiko serangan perantara. Instal sertifikat tepercaya di server dan sambungkan dengan TrustServerCertificate=no.

Batas waktu koneksi dan percobaan ulang

Konfigurasikan ketahanan koneksi dengan pengaturan batas waktu dan coba lagi:

Option Default Description
connection_timeout 0 (dinonaktifkan) Detik maksimum untuk menunggu koneksi.
connection_retries 5 Jumlah percobaan ulang saat koneksi gagal.
connection_retry_backoff_time 5 Jumlah detik untuk menunggu antar percobaan ulang.
query_timeout 0 (dinonaktifkan) Jumlah detik maksimum untuk menunggu hingga kueri selesai.

Contoh:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "connection_timeout": 30,
            "connection_retries": 3,
            "connection_retry_backoff_time": 10,
            "query_timeout": 120,
        },
    },
}

connection_timeout=0 merupakan setelan bawaan mssql-django. Karena pyodbc hanya memanggil SQLSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT, ...) saat Anda memberikan nilai positif, maka nilai baku bawaan yang bergantung pada driver yang berlaku (15 detik untuk Microsoft ODBC Driver for SQL Server). Atur nilai eksplisit sehingga upaya koneksi yang tidak responsif gagal secara prediksial.

Jika targetnya adalah Azure SQL Database tanpa server dengan auto-pause diaktifkan, gunakan setidaknya 60. Database yang dijeda secara otomatis akan dilanjutkan kembali saat percobaan koneksi pertama, dan percobaan tersebut dapat gagal dengan kesalahan 40613 selama database dilanjutkan kembali. Dengan timeout yang lebih singkat, upaya koneksi pertama habis sebelum resume selesai. connection_retries akhirnya berhasil, tetapi permintaan pertama menunggu beberapa timeout sebelum tersambung. Untuk informasi lebih lanjut, lihat Auto-pause dan auto-resume.

Collation

Atur kolase kustom untuk pencarian bidang teks:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<your-database>",
        "USER": "<your-username>",
        "PASSWORD": "<your-password>",
        "HOST": "<your-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "collation": "Chinese_PRC_CI_AS",
        },
    },
}

Beberapa koneksi database

Django mendukung menyambungkan ke beberapa database secara bersamaan. Ini berguna untuk replika baca, kueri lintas database, atau memisahkan beban kerja berdasarkan tingkat isolasi.

Konfigurasi beberapa basis data

Tentukan setiap koneksi dalam DATABASES pengaturan:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "app_db",
        "HOST": "<your-primary-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
    "readonly": {
        "ENGINE": "mssql",
        "NAME": "app_db",
        "HOST": "<your-readonly-replica>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Encrypt=yes;ApplicationIntent=ReadOnly",
        },
    },
    "analytics": {
        "ENGINE": "mssql",
        "NAME": "analytics_db",
        "HOST": "<your-analytics-server>",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "isolation_level": "READ UNCOMMITTED",
        },
    },
}

Perhatian

READ UNCOMMITTED memungkinkan pembacaan data kotor. Gunakan tingkat isolasi ini hanya untuk kueri pelaporan atau analitik di mana akurasi absolut tidak diperlukan. Untuk informasi selengkapnya, lihat Manajemen transaksi.

Mengarahkan kueri dengan perute basis data

Buat router database untuk mengarahkan operasi baca dan tulis ke koneksi yang sesuai:

class ReadReplicaRouter:
    """Route read queries to the readonly replica, writes to the primary."""

    def db_for_read(self, model, **hints):
        return "readonly"

    def db_for_write(self, model, **hints):
        return "default"

    def allow_relation(self, obj1, obj2, **hints):
        return True

    def allow_migrate(self, db, app_label, model_name=None, **hints):
        return db == "default"

Daftarkan router di settings.py:

DATABASE_ROUTERS = ["myproject.routers.ReadReplicaRouter"]

Simpan kelas router dalam file seperti myproject/routers.py.

Mengkueri database tertentu secara langsung

using() Gunakan metode untuk mengkueri alias database tertentu:

# Explicit read from analytics database
reports = AnalyticsReport.objects.using("analytics").filter(date__gte="2025-01-01")

# Write to default
Product.objects.create(name="Widget", price=9.99)

Untuk informasi selengkapnya tentang tingkat isolasi pada database per koneksi, lihat Membaca data tanpa memblokir.