Container und lokale Entwicklung mit mssql-django

Dieses Handbuch befasst sich mit der Umgebungseinrichtung für Django-Entwickler, die mit dem mssql-django Back-End in Windows, Linux, macOS, Docker-Containern, Devcontainern und CI-Pipelines arbeiten.

Voraussetzungen

  • Python 3.8 oder höher (Django 6.0 erfordert Python 3.12 und höher)
  • Docker Desktop (für containerbasierte Entwicklung)
  • Microsoft ODBC-Treiber 17 oder 18 für SQL Server. Siehe "ODBC-Treiber herunterladen" für SQL Server.

Das Hilfsprogramm sqlcmd (Go) kann einen SQL Server Container in einem einzigen Befehl erstellen. Er behandelt den Docker-Image-Pull, die Kennwortgenerierung, die Portzuweisung und den Verbindungskontext automatisch:

sqlcmd create mssql --accept-eula

So erstellen Sie einen Container mit bereits angefügter Beispieldatenbank:

sqlcmd create mssql --accept-eula --using https://aka.ms/AdventureWorksLT.bak

Speichert nach der Erstellung den Verbindungskontext, sqlcmd damit Sie sofort abfragen können:

sqlcmd query "SELECT @@VERSION"

Konfigurieren Sie Django so, dass es die Verbindungsdetails verwendet, die sqlcmd bei der Erstellung ausgegeben hat. Verwenden Sie sqlcmd config view, um sie später abzurufen:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "master",
        "USER": "sa",
        "PASSWORD": "<password from sqlcmd output>",
        "HOST": "localhost",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "TrustServerCertificate=yes",
        },
    },
}

Wenn Sie fertig sind, beenden oder löschen Sie den Container:

sqlcmd stop
sqlcmd delete

Tip

Führen Sie diesen Befehl sqlcmd create mssql --user-database mydb aus, um einen Container mit einer leeren Benutzerdatenbank zu erstellen, die für die Entwicklung bereit ist.

Lokaler SQL Server in Visual Studio Code

Die MSSQL-Erweiterung für Visual Studio Code kann lokale SQL Server Container direkt aus dem Editor erstellen:

  1. Öffnen Sie die ansicht SQL Server in der Aktivitätsleiste.
  2. Wählen Sie Verbindung hinzufügen>Lokalen SQL Server erstellen aus (oder verwenden Sie die Befehlspalette: MS SQL: Lokalen SQL Server erstellen).
  3. Wählen Sie die SQL Server Version aus, und akzeptieren Sie die EULA.
  4. Die Erweiterung ruft das Containerimage ab, generiert ein Kennwort und fügt automatisch ein Verbindungsprofil hinzu.

Sobald der Container ausgeführt wird, können Sie Datenbanken durchsuchen, Abfragen ausführen und Objekte in Visual Studio Code verwalten, bevor Sie zu Ihrem Django-Code wechseln.

Lokale SQL Server mit Docker

Wenn Sie Container lieber direkt verwalten möchten, funktioniert das offizielle SQL Server Containerimage mit zwei Umgebungsvariablen:

docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=YourStr0ngP@ssword" \
  -p 1433:1433 --name sql1 \
  -d mcr.microsoft.com/mssql/server:2022-latest

Important

Verwenden Sie MSSQL_SA_PASSWORD für SQL Server-Container. Die ältere SA_PASSWORD Variable ist veraltet. Das Kennwort muss SQL Server Komplexitätsanforderungen erfüllen: mindestens 8 Zeichen mit Großbuchstaben, Kleinbuchstaben, Ziffern und Sonderzeichen.

Warten Sie einige Sekunden, bis der Container gestartet wird, und führen Sie dann Migrationen aus:

python manage.py migrate
python manage.py createsuperuser

Dockerfile für Django-Anwendungen

Erstellen Sie eine minimale Dockerfile-Datei für eine Django-Anwendung, die eine Verbindung mit SQL Server herstellt. Der ODBC-Treiber ist die zentrale Abhängigkeit, die nicht mit dem Python-Basis-Image mitgeliefert wird:

FROM python:3-slim

# Install ODBC Driver 18 for SQL Server
RUN apt-get update && \
    apt-get install -y --no-install-recommends curl gnupg2 && \
    curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
        gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg && \
    echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" > \
        /etc/apt/sources.list.d/mssql-release.list && \
    apt-get update && \
    ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 unixodbc-dev && \
    apt-get purge -y curl gnupg2 && \
    apt-get autoremove -y && \
    rm -rf /var/lib/apt/lists/*

WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

# Collect static files
RUN python manage.py collectstatic --noinput

EXPOSE 8000
CMD ["gunicorn", "myproject.wsgi:application", "--bind", "0.0.0.0:8000"]

Ihr requirements.txt:

django>=5.2
mssql-django>=1.5
gunicorn>=22.0

Erstellen und Ausführen:

docker build -t mydjango .
docker run -e DB_HOST=host.docker.internal -e DB_NAME=mydb \
  -e DB_USER=<your-username> -e DB_PASSWORD=<your-password> \
  -p 8000:8000 mydjango

Note

Verwenden Sie host.docker.internal auf Docker Desktop (Windows und macOS), um eine SQL Server auf dem Hostcomputer zu erreichen. Verwenden Sie --network host stattdessen unter Linux.

Devcontainer-Einrichtung

Erstellen Sie eine .devcontainer/devcontainer.json für Visual Studio Code, die SQL Server als Sidecar-Dienst umfasst:

{
    "name": "Django + SQL Server",
    "image": "mcr.microsoft.com/devcontainers/python:3",
    "features": {
        "ghcr.io/devcontainers/features/docker-in-docker:2": {}
    },
    "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
    "postCreateCommand": "bash .devcontainer/post-create.sh",
    "forwardPorts": [1433, 8000],
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-mssql.mssql"
            ]
        }
    }
}

Dieser Devcontainer installiert den ODBC-Treiber und Python Abhängigkeiten, enthält jedoch keine SQL Server Instanz. Starten Sie einen innerhalb des Devcontainers mit sqlcmd create mssql --accept-eula (da Docker-in-Docker verfügbar ist) oder verwenden Sie den Docker Compose-Ansatz für einen integrierten SQL Server-Dienst.

Erstellen Sie .devcontainer/post-create.sh, um den ODBC-Treiber und die Python-Abhängigkeiten zu installieren:

#!/bin/bash
set -e

# Install ODBC Driver 18
curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
    sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" | \
    sudo tee /etc/apt/sources.list.d/mssql-release.list
sudo apt-get update
sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev

pip install -r requirements.txt

Einschließen SQL Server mit Docker Compose

Um SQL Server als Dienst in den Devcontainer einzuschließen, verwenden Sie Docker Compose:

.devcontainer/docker-compose.yml:

services:
  app:
    image: mcr.microsoft.com/devcontainers/python:3
    volumes:
      - ..:/workspace:cached
    command: sleep infinity
    depends_on:
      - db

  db:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      MSSQL_SA_PASSWORD: "YourStr0ngP@ssword"
    ports:
      - "1433:1433"

.devcontainer/devcontainer.json (Compose-Version):

{
    "name": "Django + SQL Server",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/workspace",
    "postCreateCommand": "bash .devcontainer/post-create.sh",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-mssql.mssql"
            ]
        }
    }
}

Verbinden Sie Django mit dem SQL Server-Dienst anhand des Namens:

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "mydb",
        "USER": "sa",
        "PASSWORD": "<password>",
        "HOST": "db",
        "PORT": "1433",
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": "TrustServerCertificate=yes",
        },
    },
}

Authentifizierung für die Entwicklung

Wählen Sie einen Authentifizierungsansatz basierend darauf aus, wo Ihre Anwendung ausgeführt wird und wo die Datenbank gehostet wird.

Lokale Entwicklung gegen Azure SQL

Verwenden Sie für die lokale Entwicklung für Azure SQL entweder Authentication=ActiveDirectoryDefault in OPTIONS["extra_params"] (mit mssql-django 1.7.3 und höher sowie einen kompatiblen Microsoft ODBC-Treiber) oder die TOKEN Einstellung mit DefaultAzureCredential. DefaultAzureCredential setzt Ihre az login Sitzung automatisch fort:

from azure.identity import DefaultAzureCredential

credential = DefaultAzureCredential()
token = credential.get_token("https://database.windows.net/.default").token

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": "mydb",
        "HOST": "myserver.database.windows.net",
        "PORT": "1433",
        "TOKEN": token,
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Die vollständige Authentifizierungsmatrix und Hinweise finden Sie unter Microsoft Entra-Authentifizierung mit mssql-django.

Containerentwicklung für Azure SQL

Verwenden Sie für Container, die in Azure ausgeführt werden, die Einstellung TOKEN mit ManagedIdentityCredential, um explizit ein Microsoft Entra-Zugriffstoken abzurufen:

from azure.identity import ManagedIdentityCredential

credential = ManagedIdentityCredential()
token = credential.get_token("https://database.windows.net/.default").token

DATABASES = {
  "default": {
    "ENGINE": "mssql",
    "NAME": "mydb",
    "HOST": "myserver.database.windows.net",
    "PORT": "1433",
    "TOKEN": token,
    "OPTIONS": {
      "driver": "ODBC Driver 18 for SQL Server",
    },
  },
}

Eine vollständige Liste der Authentifizierungsmethoden finden Sie unter Microsoft Entra Authentifizierung mit mssql-django.

Einrichtung der CI-Pipeline

Führen Sie Ihre Django-Testsuite mit einem SQL Server-Dienstcontainer in Ihrer CI-Pipeline aus.

GitHub Actions

name: Django Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest

    services:
      sqlserver:
        image: mcr.microsoft.com/mssql/server:2022-latest
        env:
          ACCEPT_EULA: Y
          MSSQL_SA_PASSWORD: YourStr0ngP@ssword
        ports:
          - 1433:1433
        options: >-
          --health-cmd "/opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P \"$$MSSQL_SA_PASSWORD\" -C -Q 'SELECT 1'"
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-python@v5
        with:
          python-version: "3.x"

      - name: Install ODBC Driver
        run: |
          curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
              sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
          echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/$(lsb_release -rs)/prod $(lsb_release -cs) main" | \
              sudo tee /etc/apt/sources.list.d/mssql-release.list
          sudo apt-get update
          sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev

      - name: Install dependencies
        run: pip install -r requirements.txt

      - name: Run tests
        env:
          DB_HOST: localhost
          DB_NAME: master
          DB_USER: <username>
          DB_PASSWORD: <password>
        run: python manage.py test

Tip

Ersetzen Sie für freigegebene Pipelines das Inlineplatzhalterkennwort durch einen verschlüsselten Geheimschlüssel (${{ secrets.SQL_PWD }}) und heften Sie das SQL Server Dienstimage an einen Digest an.

Azure Pipelines

trigger:
  - main

resources:
  containers:
    - container: sqlserver
      image: mcr.microsoft.com/mssql/server:2022-latest
      env:
        ACCEPT_EULA: Y
        MSSQL_SA_PASSWORD: YourStr0ngP@ssword
      ports:
        - 1433:1433

pool:
  vmImage: ubuntu-latest

services:
  sqlserver: sqlserver

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: "3.x"

  - script: |
      curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | \
          sudo gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg
      echo "deb [signed-by=/usr/share/keyrings/microsoft-prod.gpg] https://packages.microsoft.com/ubuntu/$(lsb_release -rs)/prod $(lsb_release -cs) main" | \
          sudo tee /etc/apt/sources.list.d/mssql-release.list
      sudo apt-get update
      sudo ACCEPT_EULA=Y apt-get install -y msodbcsql18 unixodbc-dev
      pip install -r requirements.txt
    displayName: Install dependencies

  - script: python manage.py test
    displayName: Run tests
    env:
      DB_HOST: localhost
      DB_NAME: master
      DB_USER: <username>
      DB_PASSWORD: <password>

Umgebungsabhängige settings.py

Konfigurieren Sie settings.py so, dass Datenbankanmeldeinformationen aus Umgebungsvariablen gelesen werden. Diese einzelne Konfiguration funktioniert für lokale Entwicklung, Docker und CI:

import os

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": os.environ.get("DB_NAME", "mydb"),
        "USER": os.environ.get("DB_USER", ""),
        "PASSWORD": os.environ.get("DB_PASSWORD", ""),
        "HOST": os.environ.get("DB_HOST", "localhost"),
        "PORT": os.environ.get("DB_PORT", "1433"),
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
            "extra_params": os.environ.get("DB_EXTRA_PARAMS", "TrustServerCertificate=yes"),
        },
    },
}

Speichern von Anmeldeinformationen in einer .env Datei für die lokale Entwicklung (hinzufügen .env zu .gitignore):

DB_HOST=localhost
DB_NAME=mydb
DB_USER=<username>
DB_PASSWORD=<password>

Laden von Umgebungsvariablen mit django-environ oder python-dotenv:

pip install django-environ
import environ

env = environ.Env()
environ.Env.read_env()  # Reads .env file

DATABASES = {
    "default": {
        "ENGINE": "mssql",
        "NAME": env("DB_NAME"),
        "USER": env("DB_USER", default=""),
        "PASSWORD": env("DB_PASSWORD", default=""),
        "HOST": env("DB_HOST", default="localhost"),
        "PORT": env("DB_PORT", default="1433"),
        "OPTIONS": {
            "driver": "ODBC Driver 18 for SQL Server",
        },
    },
}

Vorsicht

Committen Sie niemals .envDateien in die Quellcodeverwaltung. Füge der .env-Datei .gitignore hinzu.

Behandeln häufiger Containerprobleme

Symptom Ursache Beheben
Can't open lib 'ODBC Driver 18 for SQL Server' ODBC-Treiber nicht im Container installiert. Installieren Sie msodbcsql18 in Ihrem Dockerfile oder in Ihrem Post-Create-Skript.
Verbindung verweigert am Port 1433 SQL Server Container nicht bereit. Fügen Sie eine Integritätsprüfung hinzu, oder warten Sie, bis der Dienst gestartet wird.
Login failed for user '<username>' Anmeldeinformationen sind falsch, oder das Kennwort erfüllt keine Komplexitätsanforderungen. Verwenden Sie die richtige SQL-Anmeldung für Ihren Container, und stellen Sie sicher, dass das Kennwort den Komplexitätsanforderungen entspricht.
Cannot open database Die Datenbank ist noch nicht vorhanden. Erstellen Sie die Datenbank, bevor Sie migrate ausführen, oder verwenden Sie master für die Ersteinrichtung.
Langsame erste Verbindung im Container DNS-Auflösung oder Initialisierung der Anmeldeinformationskette. Verwenden Sie localhost für lokale SQL Server anstelle eines Hostnamens.
SSL Provider: [error:0A000086] TLS-Zertifikatüberprüfungsfehler mit selbstsigniertem Zertifikat. TrustServerCertificate=yes nur für die Entwicklung zu extra_params hinzufügen.