Anslutningsalternativ för mssql-django

Den OPTIONS här artikeln förklarar inställningarna för ordlistan i din Django-konfiguration DATABASES. De här inställningarna styr hur mssql-django ansluter till SQL Server via ODBC-drivrutinen.

Val av ODBC-drivrutin

Från och med mssql-django 1.7 använder bakänden ODBC Driver 18 for SQL Server som standard. Om ODBC Driver 18 inte är installerad återgår serverdelen automatiskt till ODBC Driver 17.

Note

ODBC Driver 18 aktiverar Encrypt=yes som standard och validerar servercertifikatet. Anslutningar som fungerade med Driver 17 kan sluta fungera på grund av ett förtroendefel för SSL/TLS. Så här löser du felet:

  • För lokala SQL Server installerar du ett servercertifikat från en certifikatutfärdare som dina klienter redan litar på eller importerar det befintliga servercertifikatet till varje klientförtroendearkiv. Anvisningar finns i Konfigurera Databasmotor för SQL Server för kryptering av anslutningar.
  • Om du ansluter via IP-adress eller med ett alias som inte matchar certifikatets ämne eller alternativt ämnesnamn (SAN) lägger du till HostNameInCertificate=<name-from-certificate> i extra_params.

För lokal utveckling med ett självsignerat certifikat, se TrustServerCertificate i Extra ODBC-parametrar.

Du kan ange drivrutinen uttryckligen:

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

I Linux kan du också ange den fullständiga sökvägen till drivrutinsbiblioteket:

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

Du kan ansluta med antingen ett HOST namn eller ett namngivet DSN (datakällnamn).

Ansluta med HOST

De flesta konfigurationer använder inställningen HOST direkt:

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

Ansluta med DSN

Använd ett namngivet DSN som konfigurerats i dina ODBC-datakällor:

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

Support för FreeTDS

Om du vill använda FreeTDS som ODBC-drivrutin anger du host_is_server till True. Detta talar om för serverdelen att använda HOST och PORT direkt i stället för att leta upp ett dataservernamn i 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,
        },
    },
}

Mer information om DSN-färre anslutningar med FreeTDS finns i användarhandboken för FreeTDS.

Ytterligare ODBC-parametrar

Använd extra_params för att skicka ytterligare ODBC-reťazec pripojenia parametrar. Värdet är en semikolonavgränsad sträng som läggs till i reťazec pripojenia:

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

Den här inställningen används också för nyckelord för Microsoft Entra autentisering.

När du ansluter till Azure SQL Database, Azure SQL Managed Instance, SQL-databas i Microsoft Fabric, en lyssnare för en tillgänglighetsgrupp eller en redundansklusterinstans lägger du till MultiSubnetFailover=Yes i extra_params. När servernamnet upplöses till mer än en IP-adress ansluter drivrutinen till alla dessa adresser samtidigt och använder den första som svarar. Utan den försöker föraren adresserna en i taget, och en adress som inte svarar förbrukar den återstående autentiseringstiden innan föraren går vidare till nästa. När DNS går över till en enda adress gör drivrutinen ett enda anslutningsförsök, så inställningen är säker att låta vara på.

MultiSubnetFailover=Yes har följande gränser:

  • Du kan inte använda det över ett annat protokoll än TCP.

  • Anslutning till en SQL Server-instans konfigurerad med mer än 64 IP-adresser misslyckas.

  • Du kan inte använda det med databasspegling. Drivrutinen returnerar ett fel när anslutningssträngen anger Failover_Partner, och även när servern rapporterar att databasen är speglad. Databasspegling är föråldrad i alla stödda versioner av SQL Server. Använd AlwaysOn-tillgänglighetsgrupper i stället.

Försiktighet

Använd TrustServerCertificate=yes endast för lokal utveckling med självsignerade certifikat. Använd den inte i produktion. Den inaktiverar validering av certifikatkedjan och ökar risken för angripare i mitten. Installera ett betrott certifikat på servern och anslut med TrustServerCertificate=no.

Tidsgränser för anslutningar och återförsök

Konfigurera anslutningsåterhämtning med timeout- och återförsöksinställningar:

Option Standardinställning Description
connection_timeout 0 (inaktiverad) Maximalt antal sekunder att vänta på en anslutning.
connection_retries 5 Antal återförsök vid anslutningsfel.
connection_retry_backoff_time 5 Sekunder att vänta mellan återförsök.
query_timeout 0 (inaktiverad) Maximalt antal sekunder att vänta tills en fråga har slutförts.

Example:

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 är standarden för mssql-django. Eftersom pyodbc bara anropar SQLSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT, ...) när du anger ett positivt värde, gäller drivrutinsberoende standard (15 sekunder för Microsoft ODBC-drivrutinen för SQL Server). Sätt ett explicit värde så att oresponsiva anslutningsförsök misslyckas förutsägbart.

Om målet är Azure SQL Database serverless med automatisk paus aktiverat, använd minst 60. En automatiskt pausad databas återupptas vid första anslutningsförsöket, och det försöket kan misslyckas med fel 40613 medan databasen återupptas. Vid en kortare timeout går det första kontaktförsöket ut innan återupptaget är klart. connection_retries lyckas till slut, men den första förfrågan väntar ut flera timeoutar innan den ansluter. Mer information finns i Automatisk paus och automatisk återupptagning.

Collation

Ange en anpassad sortering för textfältsökningar:

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

Flera databasanslutningar

Django stöder anslutning till flera databaser samtidigt. Detta är användbart för läsrepliker, frågor mellan databaser eller för att separera arbetsbelastningar efter isoleringsnivå.

Konfigurera flera databaser

Definiera varje anslutning i inställningen 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",
        },
    },
}

Försiktighet

READ UNCOMMITTED tillåter smutsiga läsningar. Använd endast den här isoleringsnivån för rapporterings- eller analysfrågor där absolut noggrannhet inte krävs. Mer information finns i Transaktionshantering.

Dirigera frågor med en databasrouter

Skapa en databasrouter för att dirigera läs- och skrivåtgärder till rätt anslutning:

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"

Registrera routern i settings.py:

DATABASE_ROUTERS = ["myproject.routers.ReadReplicaRouter"]

Spara routerklassen i en fil som myproject/routers.py.

Fråga en specifik databas direkt

using() Använd metoden för att fråga ett specifikt databasalias:

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

Mer information om isoleringsnivåer för databaser per anslutning finns i Läsa data utan blockering.