mssql-djangoは、Microsoft FabricのSQL Server、Azure SQL Database、Azure SQL Managed Instance、および SQL データベース用の Microsoft の Django データベース バックエンドです。 接続するには、Django の DATABASES 設定で ENGINE を "mssql" に設定します。 バックエンドは pyodbc と Microsoft ODBC Driver for SQL Server 上に構築され、Django 3.2 から 6.0、Python 3.8 から 3.14、および 2016 から 2025 SQL Serverをサポートします。
出発点を選択する
- SQL Serverとすぐに話し合う Django プロジェクトを取得するには、「クイック スタート: SQL Serverに Django を接続する」から始めます。
- パスワードレス認証を使用して Django をAzure SQLに接続するには、Microsoft Entra認証と構成のリファレンスから始めます。
- 既存の SQL Server データベースを Django に取り込むには、inspectdb を使用したモデルのリバース エンジニアリングに移動します。
- Azureに Django サイトをデプロイするには、「Azure App Serviceとコンテナーとローカル開発へのデプロイ」に移動します。
- 別の Django バックエンドまたはデータベースから移行するには、 django-mssql-backend からの移行、 他のデータベースからの移行、 または PostgreSQL からの移行に移動します。
Azure SQLの運用ベースライン
このスニペットは、運用環境向けのAzure SQL構成の開始点として使用します。
settings.py (Django データベースの構成、ミドルウェアの登録、ログ記録)、myproject/retry.py (一時的なエラー カタログとretry_on_transientデコレーター)、myproject/middleware.py (要求レベルの再試行ミドルウェア)、myapp/views.py (トランザクション ビューの例) の 4 つのファイルが組み合わせられています。
# 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,
},
},
})
retry_on_transientで、共有一時的エラー カタログと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
myproject/middleware.pyで要求レベルのミドルウェアを定義します。 両方のレイヤーが同じエラー コードのセットを認識できるように、 is_transient を再利用します。
# 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されているため、変更ビューは独自のトランザクションを開く必要があります。 各再試行で新しいトランザクションが実行されるように、 atomic() ブロックを @retry_on_transient でラップします。
# 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
このベースラインは、2 つのレイヤーで再試行を登録します。 ミドルウェアは、管理者、シグナル、その他のミドルウェアなど、装飾されたビュー以外のデータベース アクセスのバックストップとして機能します。
@retry_on_transient デコレーターを使用すると、ビュー作成者は、再試行する操作を細かく制御できます。 一時的なエラーがデコレーターをエスケープした場合、ミドルウェアは要求全体を再試行するため、最悪の場合は最大 9 回試行してからクライアントにエラーが表示されます。 その上限がレイテンシ予算に対して高すぎる場合は、レイヤーを1つ減らすか、残すレイヤーの max_retries を下げてください。
この構成の各部分の詳細については、「構成リファレンス」、接続オプション、接続プール、再試行ロジックと接続の回復性、およびMicrosoft Entra認証を参照してください。
主要な機能
-
ドロップイン対応のDjangoバックエンド:
ENGINEを"mssql"に設定すると、Django の ORM、マイグレーション、管理サイト、管理コマンドが SQL Server で動作します。 - pyodbc および ODBC Driver 18 上に構築: 既定で TLS で暗号化された接続と、Windows、Linux、および macOS での広範なプラットフォームサポート。
- ワイド バージョン マトリックス: Django 3.2 から 6.0、Python 3.8 から 3.14、および SQL Server 2016 ~ 2025。
-
Microsoft Entra ID認証: マネージド ID、サービス プリンシパル、対話型、および統合されたフローを使用したパスワードレス接続
extra_params。 - Django の移行: SQL Serverに対するスキーマの移行 (SQL Server固有の列の種類を含む)。
-
JSONField のサポート:
JSONFieldストレージと Django 参照によってサポートされるネイティブ 。 - Always Encrypted: 機密性の高い列のクライアント側暗号化。
-
一括操作: 適切なバッチサイズで SQL Server に対して実行する
bulk_createとbulk_update。 - 一時的な再試行: 接続とクエリの実行中に発生する一般的なAzure SQL一時的なエラーに対する組み込みの処理。
-
inspectdb: 既存のSQL Server スキーマから Django モデルを生成します。
概要
| 記事 | 説明 |
|---|---|
| Installation |
mssql-djangoとMicrosoft ODBC Driver for SQL Serverをインストールします。 |
| クイック スタート: Django をSQL Serverに接続する | Django プロジェクトをSQL Serverに接続し、最初の移行を実行します。 |
構成と接続
| 記事 | 説明 |
|---|---|
| 構成リファレンス | mssql-django を使用した Django DATABASES ディクショナリの完全なリファレンス。 |
| 接続オプション |
OPTIONS、 extra_params、タイムアウト、ODBC ドライバーの構成。 |
| 接続プール |
CONN_MAX_AGE、CONN_HEALTH_CHECKS、および外部プールとの連携。 |
| 再試行ロジックと接続の回復性 | 一時的なエラーを検出し、接続とクエリを再試行します。 |
| Microsoft Entra 認証 | マネージド ID、サービス プリンシパル、対話型、統合フローを使用したパスワードレス認証。 |
| セキュリティのベスト プラクティス | パラメーター化、シークレット管理、最小特権、暗号化。 |
| 常に暗号化 | 機密性の高い列のクライアント側暗号化を構成します。 |
モデル、移行、データ型
| 記事 | 説明 |
|---|---|
| データベースの移行 | SQL Server固有の列の種類など、SQL Serverに対して Django の移行を実行します。 |
| Django フィールドから SQL Server 型へのマッピング | Django モデル フィールドをSQL Serverデータ型にマップする方法。 |
| JSONField のサポート | SQL Serverおよび Django 参照でJSONFieldを使用します。 |
| inspectdb を使用してモデルをリバース エンジニアリングする | 既存のSQL Server スキーマから Django モデルを生成します。 |
| タイム ゾーンのサポート |
USE_TZ、datetimeoffset、およびタイムゾーン対応の日時。 |
データのクエリと操作
| 記事 | 説明 |
|---|---|
| 一括操作 |
bulk_create、 bulk_update、バッチ サイズのチューニング。 |
| トランザクション管理 |
atomic、分離レベル、セーブポイント、デッドロック処理。 |
| 生の SQL クエリ |
RawSQL、connection.cursor()、およびSQL Server固有の構文。 |
| ストアド プロシージャ | Django から SQL Server のストアド プロシージャを呼び出す |
デプロイ、テスト、チューニング
| 記事 | 説明 |
|---|---|
| Azure App Service にデプロイする | mssql-django を使用して Django サイトをAzure App Serviceに発送します。 |
| コンテナーとローカル開発 | Django + SQL Server 用の Docker コンテナー、devcontainers、CI パイプライン。 |
| テスト | SQL Serverに対して Django テスト スイートを実行します。 |
| パフォーマンスチューニング | インデックス、クエリ パターン、接続の再利用、バッチ サイズ。 |
| Troubleshooting | 一般的なエラー、ODBC 診断、およびログ記録。 |
mssql-django に移行する
| 記事 | 説明 |
|---|---|
| django-mssql-backend から移行する | コミュニティ django-mssql-backend パッケージから mssql-django に移行します。 |
| 他のデータベースからの移行 | Django プロジェクトを別のデータベース バックエンドからSQL Serverに移動します。 |
| PostgreSQL からの移行 | PostgreSQL から SQL Server に移行する Django 開発者向けのワンストップ ガイド。 |
関連タスク
| 記事 | 説明 |
|---|---|
| サポート ライフサイクル | サポートされている Django、Python、および SQL Server バージョン。 |
| 新着情報 | バージョン履歴とリリースのハイライト。 |
| mssql-django の制限事項とサポートされていない機能 | バックエンドの制限事項とサポートされていない機能。 |
| よくある質問 | よく寄せられる質問。 |