Контейнер и локальная разработка с помощью mssql-django

В этом руководстве описывается настройка среды для разработчиков Django, работающих с серверной mssql-django частью в Windows, Linux, macOS, контейнерах Docker, devcontainers и конвейерах CI.

Необходимые условия

  • Python 3.8 или более поздней версии (для Django 6.0 требуется Python 3.12 и более поздних версий).
  • Docker Desktop (для разработки на основе контейнеров)
  • Microsoft драйвер ODBC 17 или 18 для SQL Server. См. раздел "Скачать драйвер ODBC для SQL Server".

Служебная программа sqlcmd (Go) может создать контейнер SQL Server в одной команде. Он автоматически обрабатывает извлечение образа Docker, создание паролей, назначение порта и контекст подключения:

sqlcmd create mssql --accept-eula

Чтобы создать контейнер с примером базы данных, уже подключенной:

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

После создания sqlcmd сохраняет контекст соединения, поэтому можно сразу выполнить запрос:

sqlcmd query "SELECT @@VERSION"

Настройте Django для подключения, используя сведения о подключении, которые sqlcmd вывел при создании. Используйте sqlcmd config view для их получения позже:

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

По завершении остановите или удалите контейнер:

sqlcmd stop
sqlcmd delete

Tip

Запустите sqlcmd create mssql --user-database mydb , чтобы создать контейнер с пустой пользовательской базой данных, готовой к разработке.

Локальный SQL Server в Visual Studio Code

Расширение MSSQL для Visual Studio Code может создавать локальные контейнеры SQL Server непосредственно из редактора:

  1. Откройте представление SQL Server в строке действий.
  2. Выберите Добавить подключение>Создать локальный SQL Server (или используйте палитру команд: MS SQL: Создать локальный SQL Server).
  3. Выберите версию SQL Server и примите EULA.
  4. Расширение извлекает образ контейнера, создает пароль и добавляет профиль подключения автоматически.

После запуска контейнера можно просматривать базы данных, выполнять запросы и управлять объектами в Visual Studio Code перед переходом на код Django.

Локальный SQL Server с Docker

Если вы предпочитаете управлять контейнерами напрямую, официальный образ контейнера SQL Server работает с двумя переменными среды:

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

Используется MSSQL_SA_PASSWORD для контейнеров SQL Server. Переменная SA_PASSWORD считается устаревшей. Пароль должен соответствовать требованиям SQL Server сложности: по крайней мере 8 символов с верхним регистром, строчным регистром, цифрами и специальными символами.

Подождите несколько секунд, пока контейнер запустится, а затем выполните миграции:

python manage.py migrate
python manage.py createsuperuser

Dockerfile для приложений Django

Создайте минимальный файл Dockerfile для приложения Django, подключающегося к SQL Server. Драйвер ODBC — это ключевая зависимость, которая не поставляется с базовым образом Python:

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

Ваш requirements.txt:

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

Сборка и запуск:

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

Используйте host.docker.internal docker Desktop (Windows и macOS) для доступа к SQL Server на хост-компьютере. Вместо этого используйте --network host в Linux.

Настройка Devcontainer

Создайте .devcontainer/devcontainer.json для Visual Studio Code, включающую SQL Server в качестве сопутствующей службы:

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

Этот контейнер разработки устанавливает драйвер ODBC и зависимости Python, но не содержит экземпляр SQL Server. Запустите его внутри devcontainer с помощью sqlcmd create mssql --accept-eula (так как Docker-in-Docker доступен) или используйте подход Docker Compose для встроенной службы SQL Server.

Создайте .devcontainer/post-create.sh для установки драйвера ODBC и зависимостей Python:

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

Добавление SQL Server в Docker Compose

Чтобы включить SQL Server в качестве службы в devcontainer, используйте 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):

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

Подключите Django к службе SQL Server по имени:

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

Проверка подлинности для разработки

Выберите подход проверки подлинности в зависимости от того, где выполняется приложение и где размещена база данных.

Локальная разработка для Azure SQL

Для локальной разработки с Azure SQL используйте либо Authentication=ActiveDirectoryDefault в OPTIONS["extra_params"] (начиная с версии 1.7.3 для mssql-django и с совместимым драйвером Microsoft ODBC), либо параметр TOKEN с DefaultAzureCredential. DefaultAzureCredential автоматически определяет ваш az login сеанс:

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

Полную матрицу аутентификации и предупреждения см. в разделе Аутентификация Microsoft Entra в mssql-django.

Разработка контейнеров для Azure SQL

Для контейнеров, работающих в Azure, используйте параметр TOKEN вместе с ManagedIdentityCredential, чтобы в явном виде получить маркер доступа 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": "myserver.database.windows.net",
    "PORT": "1433",
    "TOKEN": token,
    "OPTIONS": {
      "driver": "ODBC Driver 18 for SQL Server",
    },
  },
}

Полный список методов проверки подлинности см. в статье Проверка подлинности Microsoft Entra с помощью mssql-django.

Настройка конвейера CI

Запустите набор тестов Django в контейнере службы SQL Server в конвейере CI.

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

Для общих конвейеров замените встроенный пароль заполнителя зашифрованным секретом (${{ secrets.SQL_PWD }}) и закрепите образ службы SQL Server на дайджест.

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>

Settings.py на основе переменных среды

Настройте settings.py для считывания учетных данных базы данных из переменных среды. Эта единая конфигурация работает в локальной среде разработки, Docker и 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"),
        },
    },
}

Храните учетные данные в файле .env для локальной разработки (добавьте .env в .gitignore):

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

Загрузка переменных среды с помощью django-environ или 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",
        },
    },
}

Caution

Никогда не отправляйте файлы .env в систему контроля версий. Добавьте .env в .gitignore файл.

Устранение распространенных проблем с контейнером

Симптом Причина Исправление
Can't open lib 'ODBC Driver 18 for SQL Server' Драйвер ODBC не установлен в контейнере. Установите msodbcsql18 в Dockerfile или в post-create script.
Подключение отказано через порт 1433 SQL Server контейнер не готов. Добавьте проверку работоспособности или дождитесь запуска службы.
Login failed for user '<username>' Учетные данные неверны или пароль не соответствуют требованиям сложности. Используйте правильное имя входа SQL для контейнера и убедитесь, что пароль соответствует требованиям сложности.
Cannot open database База данных еще не существует. Создайте базу данных перед запуском migrateили используйте master для начальной настройки.
Медленное первое подключение в контейнере Разрешение DNS или запуск цепочки учетных данных. Для локальной SQL Server используйте localhost вместо имени узла.
SSL Provider: [error:0A000086] Сбой проверки TLS-сертификата при использовании самоподписанного сертификата. Добавьте TrustServerCertificate=yes в extra_params только для разработки.