SQL Server için Django arka ucu - mssql-django

mssql-django Microsoft’un SQL Server, Azure SQL Veritabanı, Azure SQL Yönetilen Örneği ve Microsoft Fabric’teki SQL veritabanı için Django veritabanı arka ucudur. Bağlanmak için Django DATABASES yapılandırmanızda ENGINE değerini "mssql" olarak ayarlayın. Arka uç, pyodbc ve SQL Server için Microsoft ODBC Sürücüsü temel alınarak oluşturulmuştur ve Django 3.2–6.0, Python 3.8–3.14 ve SQL Server 2016–2025 sürümlerini destekler.

Başlangıç noktanızı seçin

Azure SQL için üretim temeli

Bu kod parçacığını üretim odaklı Azure SQL yapılandırması için başlangıç noktası olarak kullanın. Dört dosyayı birleştirir: settings.py (Django veritabanı yapılandırması, ara yazılım kaydı ve günlüğe kaydetme), myproject/retry.py (geçici hata kataloğu ve retry_on_transient dekoratör), myproject/middleware.py (istek düzeyi yeniden deneme ara yazılımı) ve myapp/views.py (örnek işlem görünümü).

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

myproject/retry.py içinde paylaşılan geçici hata kataloğunu ve retry_on_transient dekoratörünü tanımlayın:

# 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

myproject/middleware.py içinde istek düzeyindeki ara yazılımı tanımlayın. Her iki katmanın da aynı hata kodu kümesini tanıması için is_transient yeniden kullanılır:

# 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

ATOMIC_REQUESTS, False olduğundan, değiştirici görünümler kendi işlemlerini başlatmalıdır. atomic() bloğunu @retry_on_transient ile sarın; böylece her yeniden deneme yeni bir işlem çalıştırır:

# 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

Bu temel yapı, yeniden deneme mekanizmasını iki katmanda uygular. Ara yazılım, yönetici, sinyaller veya diğer ara yazılım gibi dekore edilmiş görünümlerin dışında veritabanı erişimi için bir arka uç işlevi görür. @retry_on_transient dekoratörü, görünüm yazarlarına hangi işlemlerin yeniden deneneceği üzerinde daha ayrıntılı kontrol sağlar. Geçici bir hata dekoratörden kaçarsa, ara katman tüm isteği yeniden dener; dolayısıyla istemci bir hata görmeden önce en kötü durumda en fazla dokuz deneme yapılabilir. Bu üst sınır gecikme bütçeniz için fazla yüksekse, bir katmanı kaldırın veya koruduğunuz katmanda max_retries değerini düşürün.

Bu yapılandırmanın her bir bölümü hakkında daha fazla bilgi için bkz. Yapılandırma başvurusu, Bağlantı seçenekleri, Bağlantı havuzu oluşturma, Yeniden deneme mantığı ve bağlantı dayanıklılığı ve Microsoft Entra kimlik doğrulaması.

Temel özellikler

  • Tak-çalıştır Django backend’i: ENGINE değerini "mssql" olarak ayarlayın; Django’nun ORM’si, migrasyonları, admin’i ve yönetim komutları SQL Server ile çalışır.
  • Pyodbc ve ODBC Sürücü 18 üzerine kurulmuştur: Varsayılan olarak TLS ile şifrelenmiş bağlantılar ve Windows, Linux ve macOS'ta geniş platform desteği.
  • Geniş sürüm matrisi: Django 3.2 ile 6.0, Python 3.8 ile 3.14 ve SQL Server 2016 ile 2025.
  • Microsoft Entra ID kimlik doğrulaması: extra_params aracılığıyla yönetilen kimlik, hizmet asıl sorumlusu, etkileşimli ve tümleşik akışlarla parolasız bağlantılar.
  • Django migrasyonları: SQL Server’a yönelik şema migrasyonları; buna SQL Server’a özgü sütun türleri de dahildir.
  • JSONField desteği: JSONField depolama ve Django aramaları tarafından desteklenen yerel.
  • Always Encrypted: Hassas sütunlar için istemci tarafı şifrelemesi.
  • Toplu işlemler: SQL Server'a karşı bulk_create ve bulk_update, uygun toplu iş boyutlarıyla.
  • Geçici yeniden deneme: Bağlantı ve sorgu yürütme sırasında sık karşılaşılan Azure SQL geçici hatalar için yerleşik işleme.
  • inspectdb: Mevcut SQL Server şemalarından Django modelleri oluşturun.

Get started

Makale Açıklama
Installation mssql-django ve SQL Server için Microsoft ODBC Sürücüsü'nü yükleyin.
Hızlı Başlangıç: Django'yu SQL Server bağlama Django projesini SQL Server bağlayın ve ilk geçişinizi çalıştırın.

Yapılandırma ve bağlanma

Makale Açıklama
Yapılandırma referansı mssql-django ile Django DATABASES sözlüğü için tam referans.
Bağlantı seçenekleri OPTIONS, extra_params, zaman aşımları ve ODBC sürücüsü yapılandırması.
Bağlantı havuzu oluşturma CONN_MAX_AGE, CONN_HEALTH_CHECKS ve harici havuz entegrasyonu.
Mantığı ve bağlantı dayanıklılığını yeniden deneme Geçici hataları algılayın ve bağlantıları ve sorguları yeniden deneyin.
Microsoft Entra kimlik doğrulama Yönetilen kimlik, hizmet sorumlusu, etkileşimli ve tümleşik akışlarla parolasız kimlik doğrulaması.
En iyi güvenlik uygulamaları Parametreleştirme, gizli bilgiler yönetimi, asgari ayrıcalık ve şifreleme.
Her Zaman Şifreli Hassas sütunlar için istemci tarafı şifrelemesini yapılandırın.

Modeller, geçişler ve veri türleri

Makale Açıklama
Veritabanı geçişleri SQL Server özgü sütun türleri de dahil olmak üzere SQL Server karşı Django geçişlerini çalıştırın.
Django alanlarından SQL Server veri türlerine eşlemeler Django model alanları SQL Server veri türleriyle nasıl eşlenmiştir?
JSONField desteği JSONField SQL Server ve Django aramalarıyla kullanın.
Inspectdb ile ters mühendislik modelleri Mevcut SQL Server şemalarından Django modelleri oluşturun.
Saat dilimi desteği USE_TZ, datetimeoffset ve saat dilimi bilgisine sahip tarih-saat değerleri.

Verileri sorgulama ve verilerle çalışma

Makale Açıklama
Toplu işlemler bulk_create, bulk_updateve toplu iş boyutu ayarlama.
İşlem yönetimi atomic, yalıtım düzeyleri, kayıt noktaları ve kilitlenme işleme.
Ham SQL sorguları RawSQL, connection.cursor() ve SQL Server'a özgü söz dizimi.
Saklı prosedürler Django'dan SQL Server saklı yordamları çağır.

Dağıtma, test ve ayarlama

Makale Açıklama
Azure App Service’e dağıtın Django sitesini mssql-django ile Azure App Service adresine gönder.
Konteyner ve yerel geliştirme Django + SQL Server için Docker kapsayıcıları, devcontainers ve CI işlem hatları.
Test etme Django test paketlerini SQL Server karşı çalıştırın.
Performans ayarlama Dizinler, sorgu desenleri, bağlantı yeniden kullanımı ve toplu iş boyutları.
Troubleshooting Yaygın hatalar, ODBC tanılama ve günlükleme.

mssql-django'ya geçiş

Makale Açıklama
django-mssql-backend'den geçiş Topluluk django-mssql-backend paketinden mssql-django öğesine geçin.
Diğer veritabanlarından geçiş Django projesini başka bir veritabanı arka uçtan SQL Server taşıma.
PostgreSQL'den geçiş PostgreSQL'den SQL Server taşınan Django geliştiricileri için tek seferlik kılavuz.
Makale Açıklama
Destek yaşam döngüsü Desteklenen Django, Python ve SQL Server sürümleri.
Yenilikler Sürüm geçmişi ve sürüm notlarındaki öne çıkanlar.
mssql-django'daki sınırlamalar ve desteklenmeyen özellikler Arka uç sınırlamaları ve desteklenmeyen özellikler.
SSS Sık sorulan sorular.