Kontejnerový a místní vývoj s využitím mssql-django

Tato příručka popisuje nastavení prostředí pro vývojáře Django, kteří pracují s back-endem mssql-django napříč Windows, Linuxem, macOS, kontejnery Dockeru, devcontainery a kanály CI.

Prerequisites

  • Python 3.10 až 3.14. Django 6.0 a 6.1 vyžadují Python 3.12 a pozdější verze.
  • Docker Desktop (pro vývoj založený na kontejnerech)
  • Microsoft ODBC ovladač 17 nebo 18 pro SQL Server, když použijete výchozí cestu pyodbc. Viz Stažení ovladače ODBC pro SQL Server.
  • Základní obraz kompatibilní s požadovaným mssql-python balíčkem: Windows x64, Windows ARM64 s verzemi Python 3.11 a vyššími, macOS 15 a pozdějšími verzemi, nebo Linux x64/ARM64 s glibc 2.28 a novějšími verzemi či musl 1.2 a novějšími verzemi. SUSE Linux na ARM64 není podporován.

Cesta mssql-python nevyžaduje samostatný Microsoft ODBC ovladač pro instalaci SQL Server. Stále potřebuje runtime unixODBC, protože backend importuje pyodbc, když ho Django načítá. Pro více informací viz Vybrat ovladač databáze pro mssql-django.

Nástroj sqlcmd (Go) může v jednom příkazu vytvořit kontejner SQL Server. Zpracovává vyžádání image Dockeru, generování hesla, přiřazení portu a kontext připojení automaticky:

sqlcmd create mssql --accept-eula

Vytvoření kontejneru s připojenou ukázkovou databází:

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

Po vytvoření uloží kontext připojení, sqlcmd abyste se mohli dotazovat okamžitě:

sqlcmd query "SELECT @@VERSION"

Nakonfigurujte Django tak, aby se připojovalo pomocí údajů o připojení, které sqlcmd vypsal při vytvoření. Použijte sqlcmd config view k jejich pozdějšímu načtení:

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

Až budete hotovi, zastavte nebo odstraňte kontejner:

sqlcmd stop
sqlcmd delete

Tip

Spuštěním příkazu sqlcmd create mssql --user-database mydb vytvořte kontejner s prázdnou uživatelskou databází připravenou pro vývoj.

Místní SQL Server v Visual Studio Code

Rozšíření MSSQL pro Visual Studio Code může vytvářet místní kontejnery SQL Server přímo z editoru:

  1. Otevřete zobrazení SQL Server na panelu aktivit.
  2. Vyberte Přidat připojení>Vytvořit místní SQL Server (nebo použijte Paletu příkazů: MS SQL: Vytvořit místní SQL Server).
  3. Zvolte verzi SQL Server a přijměte smlouvu EULA.
  4. Rozšíření načte image kontejneru, vygeneruje heslo a automaticky přidá profil připojení.

Po spuštění kontejneru můžete procházet databáze, spouštět dotazy a spravovat objekty v Visual Studio Code před přepnutím na kód Django.

Místní SQL Server s Dockerem

Pokud dáváte přednost přímé správě kontejnerů, oficiální image kontejneru SQL Server funguje se dvěma proměnnými prostředí:

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

Important

Používá se MSSQL_SA_PASSWORD pro kontejnery SQL Server. Starší SA_PASSWORD proměnná je zastaralá. Heslo musí splňovat požadavky na složitost SQL Server: nejméně 8 znaků s velkými písmeny, malými písmeny, číslicemi a speciálními znaky.

Počkejte několik sekund, než se kontejner spustí, a pak spusťte migrace:

python manage.py migrate
python manage.py createsuperuser

Dockerfile pro aplikace Django

Vytvořte minimální Dockerfile pro aplikaci Django, která se připojuje k SQL Server přes výchozí cestu pyodbc. Ovladač ODBC je klíčovou závislostí, která není součástí základní image Python:

FROM python:3.12-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 && \
    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"]

Important

Nepřidávejte apt-get autoremove -y po vymazání. Odstraní libgssapi-krb5-2, kterou ODBC ovladač načte za běhu, ale neoznačí ji za závislost. Sestavení je přesto úspěšné a následně všechna spojení selžou. Chyba pyodbc je zavádějící: verze 18 se nepodařilo načíst, mssql-django se vrací k verzi 17 a chyba označuje chybějící verzi 17 místo verze 18, která selhala.

Vaše requirements.txt:

django>=5.2,<6.2
mssql-django>=2.0
gunicorn>=22.0

Pokud vaše databázové alias používá cestu ovladače mssql-python s "python_driver": "mssql_python", stále potřebujete unixODBC, protože backend při načítání Django importuje pyodbc. Nepotřebujete Microsoft repozitář balíčků ani msodbcsql18, takže instalační blok ODBC se zmenšuje na:

RUN apt-get update && \
    apt-get install -y --no-install-recommends unixodbc libkrb5-3 libgssapi-krb5-2 && \
    rm -rf /var/lib/apt/lists/*

Sestavení a spuštění:

docker build -t mydjango .
docker run -e "DB_HOST=host.docker.internal" -e "DB_NAME=<database>" \
  -e "DB_USER=<user_id>" -e "DB_PASSWORD=<password>" \
  -p 8000:8000 mydjango

Note

Použijte v Docker Desktopu (Windows a macOS) host.docker.internal pro přístup k serveru SQL Server na hostitelském počítači. V Linuxu použijte --network host místo toho.

Nastavení devcontaineru

Vytvořte .devcontainer/devcontainer.json pro Visual Studio Code se službou SQL Server jako sidecar:

{
    "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"
            ]
        }
    }
}

Tento devcontainer instaluje ODBC ovladač pro výchozí cestu pyodbc a Python závislosti, ale neobsahuje instanci SQL Server. Spusťte ho uvnitř devcontaineru pomocí sqlcmd create mssql --accept-eula (protože je k dispozici Docker-in-Docker) nebo použijte přístup Docker Compose pro integrovanou službu SQL Server. Pokud použijete možnost mssql-python, nahraďte ve skriptu post-create instalaci msodbcsql18 za sudo apt-get install -y unixodbc libkrb5-3 libgssapi-krb5-2.

Vytvořte .devcontainer/post-create.sh a nainstalujte ovladač ODBC pro pyodbc a závislosti Pythonu:

#!/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

Zahrnutí SQL Server do Docker Compose

Pokud chcete do devcontaineru zahrnout SQL Server jako službu, použijte 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: "<strong_password>"
    ports:
      - "1433:1433"

.devcontainer/devcontainer.json (Složená verze):

{
    "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"
            ]
        }
    }
}

Připojte Django ke službě SQL Server podle názvu:

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

Ověřování pro vývoj

Zvolte přístup ověřování na základě toho, kde je vaše aplikace spuštěná a kde je databáze hostovaná.

Místní vývoj proti Azure SQL

Pro místní vývoj pro Azure SQL použijte buď Authentication=ActiveDirectoryDefault v TOKEN v pyodbc, nebo nastavení DefaultAzureCredential s OPTIONS["extra_params"]. DefaultAzureCredential automaticky naváže na vaši az login relaci:

from azure.identity import DefaultAzureCredential

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

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

Kompletní matici metod ověřování a upozornění najdete v tématu ověřování Microsoft Entra pomocí mssql-django.

Vývoj kontejnerů pro Azure SQL

Pro kontejnery spuštěné v Azure použijte nastavení TOKEN společně s ManagedIdentityCredential k explicitnímu získání přístupového tokenu Microsoft Entra:

from azure.identity import ManagedIdentityCredential

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

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

Úplný seznam metod ověřování najdete v tématu Microsoft Entra ověřování pomocí mssql-django.

Nastavení CI pipeline

Spusťte testovací sadu Django v CI pipeline s kontejnerem služby SQL Server.

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: "<strong_password>"
        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.12"

      - name: Install ODBC Driver for pyodbc
        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: "<user_id>"
          DB_PASSWORD: "<password>"
        run: python manage.py test

Tip

U sdílených kanálů nahraďte inline zástupné heslo šifrovaným tajným údajem (${{ secrets.SQL_PWD }}) a připněte image služby SQL Server ke konkrétnímu digestu.

Azure Pipelines

trigger:
  - main

resources:
  containers:
    - container: sqlserver
      image: mcr.microsoft.com/mssql/server:2022-latest
      env:
        ACCEPT_EULA: Y
        MSSQL_SA_PASSWORD: "<strong_password>"
      ports:
        - 1433:1433

pool:
  vmImage: ubuntu-latest

services:
  sqlserver: sqlserver

steps:
  - task: UsePythonVersion@0
    inputs:
      versionSpec: "3.12"

  - 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: "<user_id>"
      DB_PASSWORD: "<password>"

Settings.py založené na prostředí

Nakonfigurujte settings.py, aby načítal přihlašovací údaje k databázi z proměnných prostředí. Tato jediná konfigurace funguje napříč místním vývojem, Dockerem a 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"),
        },
    },
}

Uložení přihlašovacích údajů do .env souboru pro místní vývoj (přidat .env do .gitignore):

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

Načtení proměnných prostředí pomocí django-environ nebo python-dotenv:

pip install django-environ
import environ

env = environ.Env()
environ.Env.read_env()  # Reads .env from the directory holding this settings 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",
            "extra_params": env("DB_EXTRA_PARAMS", default="TrustServerCertificate=yes"),
        },
    },
}

Caution

Nikdy neukládejte soubory .env do správy zdrojových kódů. Přidejte .env do .gitignore souboru.

Řešení běžných problémů s kontejnery

Symptom Příčina Opravit
Can't open lib 'ODBC Driver 18 for SQL Server' ODBC ovladač není nainstalován v kontejneru pro cestu pyodbc, nebo apt-get autoremove je po instalaci odstraněn.libgssapi-krb5-2 Nainstalujte msodbcsql18 do souboru Dockerfile nebo skriptu post-create a potom už nespouštějte apt-get autoremove.
Can't open lib 'ODBC Driver 17 for SQL Server' když jste instalovali verzi 18 Verze 18 je registrována, ale nenačítá se, takže mssql-django se vrací k verzi 17, která není nainstalovaná. Obvyklou příčinou je chybějící libgssapi-krb5-2. Nainstalujte libgssapi-krb5-2 a nespouštějte apt-get autoremove po odstranění curl.
Error loading pyodbc module: libodbc.so.2 Kontejner nemá runtime unixODBC. Backend importuje pyodbc, když ho Django načítá, i přes cestu mssql-python. Nainstalujte unixodbc (nebo unixodbc-dev).
DDBC Error: Failed to load the driver Ovladač mssql-pythonu nemůže načíst vlastní závislosti. Nainstalujte libkrb5-3 a libgssapi-krb5-2.
Připojení odmítnuto na portu 1433 SQL Server kontejner není připravený. Přidejte kontrolu stavu nebo počkejte, než se služba spustí.
Login failed for user '<user_id>' Přihlašovací údaje jsou nesprávné nebo heslo nesplňuje požadavky na složitost. Při použití mssql-python se u neexistující databáze zobrazí stejná zpráva. Použijte správné přihlášení SQL pro váš kontejner a ujistěte se, že heslo splňuje požadavky na složitost. Pokud jsou přihlašovací údaje správné, ověřte, že databáze v NAME existuje.
Cannot open database Databáze ještě neexistuje. Cesta pyodbc hlásí tento případ; místo toho hlásí cesta Login failed mssql-python. Vytvořte databázi před spuštěním migratenebo použijte master pro počáteční instalaci.
Pomalé první připojení v kontejneru Překlad DNS nebo spouštění řetězce přihlašovacích údajů. Pro místní SQL Server použijte localhost místo názvu hostitele.
SSL Provider: [error:0A000086] Selhání ověření certifikátu TLS u certifikátu podepsaného sám sebou Přidejte TrustServerCertificate=yes do extra_params pouze pro vývoj.