Django-back-end voor SQL Server - mssql-django

mssql-django is de Django-databaseback-end van Microsoft voor SQL Server, Azure SQL Database, Azure SQL Managed Instance en de SQL-database in Microsoft Fabric. Stel ENGINE in op "mssql" in uw Django DATABASES-configuratie om verbinding te maken. De back-end bouwt voort op pyodbc en het Microsoft ODBC-stuurprogramma voor SQL Server en ondersteunt Django 3.2 tot en met 6.0, Python 3.8 tot en met 3.14 en SQL Server 2016 tot en met 2025.

Uw beginpunt kiezen

Productiebasislijn voor Azure SQL

Gebruik dit fragment als uitgangspunt voor een productiegerichte Azure SQL configuratie. Het combineert vier bestanden: settings.py (de Django-databaseconfiguratie, middlewareregistratie en logboekregistratie), myproject/retry.py (de tijdelijke foutcatalogus en retry_on_transient decorator), myproject/middleware.py (de middleware op aanvraagniveau voor opnieuw proberen) en myapp/views.py (een voorbeeld van transactionele weergave).

# settings.py

import logging.config
import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ["SQL_DATABASE"],          # for example, appdb
        "HOST": os.environ["SQL_SERVER"],            # for example, contoso.database.windows.net
        "PORT": "1433",
        "CONN_MAX_AGE": 300,                         # reuse pooled connections for 5 minutes
        "CONN_HEALTH_CHECKS": True,                  # validate connections before reuse (Django 4.1 and later)
        "ATOMIC_REQUESTS": False,                    # wrap mutating views in transactions explicitly (see the following view example)
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": (
                "Authentication=ActiveDirectoryMsi;"
                "Encrypt=yes;"
                "TrustServerCertificate=no;"
                # ODBC driver reconnects connections dropped while idle.
                "ConnectRetryCount=3;"
                "ConnectRetryInterval=10;"
            ),
            # Backend-level retry for the initial connect call. Complements
            # ConnectRetryCount, which only covers idle drops on an
            # already-established connection.
            # See Retry logic and connection resilience for the recognized error list.
            "connection_retries": 3,
            "connection_retry_backoff_time": 5,
        },
    },
}

MIDDLEWARE = [
    # Defined in myproject/middleware.py. Catches transient OperationalErrors
    # and retries the request. Add "1205" (deadlock victim) and "1222"
    # (lock-request timeout) to TRANSIENT_ERROR_CODES to also retry
    # statement-level failures.
    "myproject.middleware.DatabaseRetryMiddleware",
    "django.middleware.security.SecurityMiddleware",
    # ... your other middleware
]

LOGGING_CONFIG = None
logging.config.dictConfig({
    "version": 1,
    "disable_existing_loggers": False,
    "formatters": {
        "json": {
            "format": (
                '{"time":"%(asctime)s","level":"%(levelname)s",'
                '"logger":"%(name)s","message":"%(message)s"}'
            ),
        },
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "json",
        },
    },
    "loggers": {
        "django.db.backends": {
            "handlers": ["console"],
            "level": "WARNING",      # raise to INFO or DEBUG to capture SQL
            "propagate": False,
        },
        "django.request": {
            "handlers": ["console"],
            "level": "WARNING",
            "propagate": False,
        },
        "mssql": {
            "handlers": ["console"],
            "level": "INFO",
            "propagate": False,
        },
    },
})

Definieer de gedeelde catalogus met tijdelijke fouten en de retry_on_transient decorator in myproject/retry.py:

# myproject/retry.py
import functools
import logging
import random
import re
import time

from django.db import OperationalError, connection

logger = logging.getLogger(__name__)

TRANSIENT_ERROR_CODES = {
    "64", "233", "4221",
    "10053", "10054", "10928", "10929",
    "40197", "40501", "40613",
    "49918", "49919", "49920",
    # Add "4060" only if targeting Azure SQL with geo-replication failover.
    # Add "1205" (deadlock victim) and "1222" (lock-request timeout) to
    # also retry statement-level failures.
}

# Microsoft ODBC driver formats native error codes as "(<number>)" in the
# message. Parenthesized matches avoid false positives for short codes like "64".
_CODE_RE = re.compile(r"\((\d+)\)")


def is_transient(error):
    codes_in_message = set(_CODE_RE.findall(str(error)))
    return bool(codes_in_message & TRANSIENT_ERROR_CODES)


def retry_on_transient(max_retries=3, base_delay=1, max_delay=30):
    """Retry on transient database errors with exponential backoff and full jitter."""

    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            for attempt in range(max_retries + 1):
                try:
                    return func(*args, **kwargs)
                except OperationalError as e:
                    if attempt < max_retries and is_transient(e):
                        capped = min(max_delay, base_delay * (2 ** attempt))
                        delay = random.uniform(0, capped)
                        logger.warning(
                            "Transient error in %s (attempt %d/%d), retrying in %.2fs: %s",
                            func.__name__, attempt + 1, max_retries, delay, e
                        )
                        connection.close()
                        time.sleep(delay)
                        continue
                    raise
        return wrapper
    return decorator

Definieer de middleware op aanvraagniveau in myproject/middleware.py. Het hergebruikt is_transient, zodat beide lagen dezelfde set foutcodes herkennen:

# myproject/middleware.py
import logging
import random
import time

from django.db import OperationalError, connection

from myproject.retry import is_transient

logger = logging.getLogger(__name__)


class DatabaseRetryMiddleware:
    """Retry the entire request on transient database errors."""

    def __init__(self, get_response):
        self.get_response = get_response
        self.max_retries = 3
        self.base_delay = 1   # seconds; doubled each attempt
        self.max_delay = 30   # cap on a single sleep, regardless of attempt

    def __call__(self, request):
        for attempt in range(self.max_retries + 1):
            try:
                return self.get_response(request)
            except OperationalError as e:
                if attempt < self.max_retries and is_transient(e):
                    capped = min(self.max_delay, self.base_delay * (2 ** attempt))
                    delay = random.uniform(0, capped)
                    logger.warning(
                        "Transient DB error (attempt %d/%d), retrying in %.2fs: %s",
                        attempt + 1, self.max_retries, delay, e
                    )
                    connection.close()
                    time.sleep(delay)
                    continue
                raise

Omdat ATOMIC_REQUESTSFalse is, moeten weergaven die wijzigingen aanbrengen hun eigen transactie openen. Wikkel het atomic()-blok in met @retry_on_transient, zodat elke nieuwe poging in een nieuwe transactie wordt uitgevoerd:

# myapp/views.py
from django.db import transaction
from django.http import JsonResponse

from myproject.retry import retry_on_transient
from .models import Order


# Exponential backoff with full jitter: sleeps random within [0,2], [0,4], [0,8] seconds.
@retry_on_transient(max_retries=3, base_delay=2)
def submit_order(request, order_id):
    with transaction.atomic():
        order = Order.objects.select_for_update().get(id=order_id)
        order.status = "submitted"
        order.save()
    return JsonResponse({"id": order.id, "status": order.status})

Note

Deze basislijn registreert nieuwe pogingen op twee niveaus. De middleware fungeert als backstop voor databasetoegang buiten versierde weergaven, zoals de beheerder, signalen of andere middleware. De @retry_on_transient decorator geeft view-auteurs fijnmazigere controle over welke bewerkingen opnieuw worden uitgevoerd. Als een tijdelijke fout ontsnapt aan de decorator, voert de middleware de hele aanvraag opnieuw uit, dus het ergste geval is maximaal negen pogingen voordat de client een fout ziet. Als dat plafond te hoog is voor uw latentiebudget, laat dan één laag vallen of verlaag max_retries op de laag die u behoudt.

Zie configuratieverwijzing, verbindingsopties, groepsgewijze verbindingen, logica en verbindingstolerantie opnieuw proberen enMicrosoft Entra verificatie voor meer informatie over elk onderdeel van deze configuratie.

Belangrijkste kenmerken

  • Direct inzetbare Django-backend: Stel ENGINE in op "mssql" en Django's ORM, migraties, beheeromgeving en beheeropdrachten werken met SQL Server.
  • Gebouwd op pyodbc en ODBC-stuurprogramma 18: tls-versleutelde verbindingen standaard en brede platformondersteuning op Windows, Linux en macOS.
  • Brede versiematrix: Django 3.2 tot en met 6.0, Python 3.8 tot en met 3.14 en SQL Server 2016 tot en met 2025.
  • Microsoft Entra ID verificatie: verbindingen zonder wachtwoord met beheerde identiteit, service-principal, interactieve en geïntegreerde stromen via extra_params.
  • Django-migraties: Schemamigraties voor SQL Server, inclusief SQL Server specifieke kolomtypen.
  • JSONField-ondersteuning: Systeemeigen JSONField ondersteund door de nvarchar(max) -opslag en Django-zoekacties.
  • Always Encrypted: Versleuteling aan de clientzijde voor gevoelige kolommen.
  • Bulkbewerkingen: bulk_create en bulk_update op SQL Server met passende batchgroottes.
  • Opnieuw proberen bij tijdelijke fouten: Ingebouwde afhandeling van veelvoorkomende tijdelijke Azure SQL-fouten tijdens het tot stand brengen van verbindingen en het uitvoeren van query’s.
  • inspectdb: Django-modellen genereren op basis van bestaande SQL Server schema's.

Get started

Artikel Description
Installation Installeer mssql-django en het Microsoft ODBC-stuurprogramma voor SQL Server.
Quickstart: Django verbinden met SQL Server Verbind een Django-project met SQL Server en voer uw eerste migratie uit.

Configureren en verbinding maken

Artikel Description
Configuratiereferentie Volledige referentie voor de Django-woordenlijst DATABASES met mssql-django.
Verbindingsopties OPTIONS, , extra_paramstime-outs en configuratie van ODBC-stuurprogramma.
Groepsgewijze verbindingen CONN_MAX_AGE, CONN_HEALTH_CHECKS, en integratie van externe pools.
Logica en verbindingstolerantie opnieuw proberen Tijdelijke fouten detecteren en verbindingen en query's opnieuw proberen.
Microsoft Entra-authenticatie Wachtwoordloze authenticatie met beheerde identiteit, service principal, interactieve en geïntegreerde methoden.
Aanbevolen procedures voor beveiliging Parameters, geheimenbeheer, minimale bevoegdheden en versleuteling.
Altijd versleuteld Configureer versleuteling aan de clientzijde voor gevoelige kolommen.

Modellen, migraties en gegevenstypen

Artikel Description
Databasemigraties Voer Django-migraties uit op SQL Server, inclusief SQL Server-specifieke kolomtypen.
Django-veld voor SQL Server typetoewijzingen Hoe Django-modelvelden worden toegewezen aan SQL Server gegevenstypen.
Ondersteuning voor JSONField Gebruiken JSONField met SQL Server en Django-zoekacties.
Genereer modellen via reverse engineering met inspectdb Django-modellen genereren op basis van bestaande SQL Server schema's.
Ondersteuning voor tijdzones USE_TZ, datetimeoffset en tijdzonebewuste datum/tijd.

Query's uitvoeren en werken met gegevens

Artikel Description
Bulkacties bulk_create, bulk_updateen batchgrootte afstemmen.
Transactiebeheer atomic, isolatieniveaus, opslagpunten en impasseafhandeling.
Onbewerkte SQL-query's RawSQL, connection.cursor()en SQL Server-specifieke syntaxis.
Opgeslagen procedures Roep SQL Server opgeslagen procedures van Django aan.

Implementeren, testen en afstemmen

Artikel Description
Implementeren in Azure App Service Verzend een Django-site naar Azure App Service met mssql-django.
Container en lokale ontwikkeling Docker-containers, devcontainers en CI-pijplijnen voor Django + SQL Server.
Testen Voer Django-testsuites uit op SQL Server.
Performance-optimalisatie Indexen, querypatronen, hergebruik van verbindingen en batchgrootten.
Troubleshooting Veelvoorkomende fouten, diagnostische ODBC-gegevens en logboekregistratie.

Migreren naar mssql-django

Artikel Description
Migreren vanuit django-mssql-backend Stap over van het communitypakket django-mssql-backend naar mssql-django.
Migreren vanuit andere databases Verplaats een Django-project van een andere databaseback-end naar SQL Server.
Migreren vanuit PostgreSQL Eenmalige handleiding voor Django-ontwikkelaars die overstappen van PostgreSQL naar SQL Server.
Artikel Description
Ondersteuningslevenscyclus Ondersteunde Versies van Django, Python en SQL Server.
Wat is er nieuw Versiegeschiedenis en release-hoogtepunten.
Beperkingen en niet-ondersteunde functies in mssql-django Beperkingen voor back-end en niet-ondersteunde functies.
FAQ Veelgestelde vragen.