Opcje połączenia dla mssql-django

W tym artykule wyjaśniono ustawienia słownika OPTIONS w konfiguracji Django DATABASES . Te ustawienia kontrolują, jak mssql-django łączy się z SQL Server.

Wybór sterownika bazy danych w Python

mssql-django W wersji 2.0 i nowszych połączenie odbywa się za pośrednictwem pyodbc, domyślnego, lub sterownika mssql-python firmy Microsoft. Wybierz mssql-python dla aliasu bazy danych przy użyciu opcji python_driver:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "<database>",
        "USER": "<user_id>",
        "PASSWORD": "<password>",
        "HOST": "<server>",
        "PORT": "1433",
        "OPTIONS": {
            "python_driver": "mssql_python",
        },
    },
}

Nie ustawiaj driver na tej ścieżce. Ścieżka mssql-python ignoruje opcje driver, dsn, host_is_server i unicode_results, weryfikuje extra_params względem listy dozwolonych wartości i nie włącza MARS. Pełną listę różnic w zachowaniu można znaleźć w artykule Wybierz sterownik bazy danych dla mssql-django. Reszta tego artykułu opisuje domyślną pyodbc ścieżkę, chyba że zaznaczono inaczej.

Wybór sterownika ODBC

Na ścieżce pyodbc zaplecze domyślnie korzysta ze sterownika ODBC Driver 18 for SQL Server. Jeśli sterownik ODBC 18 nie jest zainstalowany, zaplecze automatycznie wraca do sterownika ODBC 17. Jawnie skonfigurowany sterownik nie przełącza się na ustawienie zapasowe.

Note

Sterownik ODBC 18 domyślnie włącza Encrypt=yes i weryfikuje certyfikat serwera. Połączenia, które pracowały z sterownikiem 17, mogą zakończyć się niepowodzeniem z powodu błędu zaufania SSL/TLS. Aby rozwiązać problem:

  • W przypadku SQL Server lokalnych zainstaluj certyfikat serwera z urzędu certyfikacji, któremu już ufają klienci, lub zaimportuj istniejący certyfikat serwera do każdego magazynu zaufania klienta. Aby uzyskać instrukcje, zobacz Konfigurowanie SQL Server Database Engine na potrzeby szyfrowania połączeń.
  • Jeśli łączysz się za pomocą adresu IP lub aliasu, który nie odpowiada nazwie podmiotu certyfikatu ani alternatywnej nazwie podmiotu (SAN), dodaj HostNameInCertificate=<name-from-certificate> do extra_params.

Aby uzyskać informacje na temat lokalnego tworzenia aplikacji z użyciem certyfikatu z podpisem własnym, zobacz TrustServerCertificate w sekcji Dodatkowe parametry ODBC.

Sterownik można określić jawnie:

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",
        },
    },
}

W systemie Linux można również określić pełną ścieżkę do biblioteki sterowników:

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 kontra HOST

Możesz nawiązać połączenie przy użyciu HOST nazwy lub nazwy DSN (nazwa źródła danych).

Nawiązywanie połączenia z hostem

Większość konfiguracji używa tego HOST ustawienia bezpośrednio:

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",
        },
    },
}

Połącz za pomocą DSN

Użyj nazwy DSN skonfigurowanej w źródłach danych ODBC:

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

Obsługa usługi FreeTDS

Aby używać FreeTDS jako sterownika ODBC, ustaw host_is_server na True. Informuje to backend, aby używał bezpośrednio elementów HOST i PORT zamiast wyszukiwać nazwę serwera danych w 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,
        },
    },
}

Aby uzyskać więcej informacji na temat połączeń bez DSN w FreeTDS, patrz podręcznik użytkownika FreeTDS.

Dodatkowe parametry ODBC

Użyj extra_params, aby przekazać dodatkowe parametry ciągu połączenia ODBC. Wartość jest ciągiem rozdzielanym średnikami dołączonym do parametry połączenia:

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",
        },
    },
}

To ustawienie jest również używane dla słów kluczowych uwierzytelniania Microsoft Entra.

Podczas łączenia z Azure SQL Database, Azure SQL Managed Instance, bazą SQL w Microsoft Fabric, słuchaczem grupy dostępności lub instancją klastra failover, dodaj MultiSubnetFailover=Yes do extra_params. Gdy nazwa serwera jest rozpoznawana jako więcej niż jeden adres IP, sterownik łączy się jednocześnie ze wszystkimi tymi adresami i używa tego, który odpowie jako pierwszy. Bez niego sterownik próbuje adresów po kolei, a adres, który nie odpowiada, wykorzystuje pozostały limit czasu uwierzytelniania, zanim sterownik przejdzie do następnego. Gdy nazwa DNS jest rozwiązywana do jednego adresu, sterownik podejmuje tylko jedną próbę połączenia, więc to ustawienie można bezpiecznie pozostawić włączone.

MultiSubnetFailover=Yes ma następujące granice:

  • Nie możesz używać go przez inny protokół niż TCP.

  • Połączenie z instancją SQL Server skonfigurowaną z ponad 64 adresami IP kończy się niepowodzeniem.

  • Nie da się jej używać z mirroringiem bazy danych. Sterownik zwraca błąd, gdy w parametrach połączenia określono Failover_Partner, a także gdy serwer zgłasza, że baza danych jest dublowana. Dublowanie bazy danych jest przestarzałe we wszystkich obsługiwanych wersjach SQL Server. Zamiast tego użyj grup dostępności Always On.

Caution

Używaj TrustServerCertificate=yes tylko do programowania lokalnego z certyfikatami z podpisem własnym. Nie używaj go w środowisku produkcyjnym. Wyłącza weryfikację łańcucha certyfikatów i zwiększa ryzyko ataku typu man-in-the-middle. Zainstaluj zaufany certyfikat na serwerze i nawiąż połączenie za pomocą polecenia TrustServerCertificate=no.

Wyłącz MARS

W ścieżce pyodbc zaplecze domyślnie włącza funkcję Multiple Active Result Sets (MARS), gdy używa sterownika Microsoft ODBC w systemie Windows. Niektóre punkty końcowe odrzucają słowo kluczowe MARS_Connection, w tym Microsoft Fabric Warehouse. Aby połączyć się z jednym z tych punktów końcowych, ustaw MARS_Connection=no w elemencie extra_params tego aliasu:

DATABASES = {
    "warehouse": {
        "ENGINE": "mssql",
        "NAME": "<database>",
        "USER": "<user_id>",
        "PASSWORD": "<password>",
        "HOST": "<server>.datawarehouse.fabric.microsoft.com",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "Authentication=ActiveDirectoryServicePrincipal;MARS_Connection=no",
        },
    },
}

Począwszy od wersji 2.0 mssql-django, jawna wartość MARS_Connection jest uwzględniana, a dopasowanie nie rozróżnia wielkości liter, więc backend nie dołącza kolidującej wartości domyślnej. W wersji 1.8.0 i wcześniejszych domyślnie Windows nadpisywał wartość jawną i połączenie się nie powiodło.

Przy wyłączonym MARS QuerySet.iterator() wczytuje cały wynik do pamięci, zanim zwróci wiersze, aby zagnieżdżone zapytanie mogło ponownie użyć tego samego połączenia. Uwzględnij koszt pamięci w dużych zestawach zapytań.

W przypadku innych metod uwierzytelniania zachowaj odpowiednie ustawienia uwierzytelniania i dołącz MARS_Connection=no do extra_params. To ustawienie połączenia nie oznacza pełnego wsparcia Microsoft Fabric Warehouse dla migracji Django ani innych funkcji SQL Server.

Ścieżka mssql-python nie włącza funkcji MARS i odrzuca słowo kluczowe MARS_Connection, więc to ustawienie dotyczy tylko pyodbc.

Limity czasu połączenia i ponowne próby

Skonfiguruj odporność połączenia przy użyciu limitu czasu i ustawień ponawiania prób:

Option Domyślnie Description
connection_timeout 0 (wyłączone) Maksymalna liczba sekund oczekiwania na połączenie.
connection_retries 5 Liczba ponownych prób w przypadku niepowodzenia połączenia.
connection_retry_backoff_time 5 Sekundy oczekiwania między ponownymi próbami.
query_timeout 0 (wyłączone) Maksymalna liczba sekund oczekiwania na ukończenie zapytania.

Przykład:

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 jest ustawieniem domyślnym w mssql-django. Ponieważ pyodbc wywołuje SQLSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT, ...) tylko wtedy, gdy podasz dodatnią wartość, obowiązuje domyślna funkcja zależna od sterownika (15 sekund dla sterownika Microsoft ODBC dla SQL Server). Ustaw jawną wartość, aby próby połączenia bez odpowiedzi kończyły się przewidywalnym niepowodzeniem.

Jeśli obiektem docelowym jest Azure SQL Database serverless z włączonym automatycznym wstrzymywaniem, użyj co najmniej 60. Automatycznie wstrzymana baza danych wznawia się przy pierwszej próbie połączenia, która może zakończyć się błędem 40613, podczas gdy baza danych wznawia działanie. Przy krótszym czasie pierwsza próba połączenia kończy się przed zakończeniem CV. connection_retries Ostatecznie się udaje, ale pierwsze żądanie czeka na kilka przerw, zanim się połączy. Więcej informacji znajdziesz w sekcji Automatyczne wstrzymywanie i automatyczne wznawianie.

Collation

Ustaw niestandardową kolejność sortowania dla wyszukiwania w polu tekstowym:

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",
        },
    },
}

Wiele połączeń bazy danych

Platforma Django obsługuje łączenie się z wieloma bazami danych jednocześnie. Jest to przydatne w przypadku replik do odczytu, zapytań między bazami danych lub rozdzielania obciążeń według poziomu izolacji.

Konfigurowanie wielu baz danych

Zdefiniuj każde połączenie w ustawieniu DATABASES :

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",
        },
    },
}

Caution

READ UNCOMMITTED zezwala na brudne odczyty. Użyj tego poziomu izolacji tylko w przypadku zapytań raportowania lub analizy, w których bezwzględna dokładność nie jest wymagana. Aby uzyskać więcej informacji, zobacz Zarządzanie transakcjami.

Kierowanie zapytań za pomocą routera bazy danych

Utwórz router bazy danych w celu kierowania operacji odczytu i zapisu do odpowiedniego połączenia:

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"

Zarejestruj router w programie settings.py:

DATABASE_ROUTERS = ["myproject.routers.ReadReplicaRouter"]

Zapisz klasę routera w pliku takim jak myproject/routers.py.

Bezpośrednie wykonywanie zapytań względem określonej bazy danych

Użyj metody , using() aby wysłać zapytanie do określonego aliasu bazy danych:

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

Aby uzyskać więcej informacji na temat poziomów izolacji w bazach danych dla poszczególnych połączeń, zobacz Odczyt danych bez blokowania.