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

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

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

  • Python 3.10 по 3.14. Django 6.0 и 6.1 требуют версий Python 3.12 и более поздних.
  • Docker Desktop (для разработки на основе контейнеров)
  • Microsoft ODBC Driver 17 или 18 для SQL Server, когда вы используете стандартный путь pyodbc. См. раздел "Скачать драйвер ODBC для SQL Server".
  • Базовый образ, совместимый с необходимым mssql-python пакетом: Windows x64, Windows ARM64 с Python 3.11 и более поздними версиями, macOS 15 и более поздние версии, или Linux x64/ARM64 с glibc 2.28 и более поздними версиями, или musl 1.2 и более поздние версии. SUSE Linux на ARM64 не поддерживается.

Путь mssql-python не требует отдельного драйвера Microsoft ODBC для установки SQL Server. Всё равно нужен unixODBC runtime, потому что бэкенд импортирует pyodbc при загрузке Django. Для получения дополнительной информации см. Выберите драйвер базы данных для mssql-django.

Служебная программа 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=<strong_password>" \
  -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 через стандартный путь pyodbc. Драйвер ODBC — это ключевая зависимость, которая не поставляется с базовым образом 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

Не добавляйте apt-get autoremove -y после очистки. Он удаляет libgssapi-krb5-2, который драйвер ODBC загружает во время выполнения, но не объявляет как зависимость. Сборка по-прежнему выполняется успешно, и после этого каждое соединение завершается сбоем. Ошибка pyodbc вводит в заблуждение: версия 18 не загружается, mssql-django возвращается к версии 17, и ошибка называет отсутствующую версию 17, а не неудачную версию 18.

Ваш requirements.txt:

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

Если псевдоним вашей базы данных использует путь драйвера mssql-python с "python_driver": "mssql_python", вам всё равно нужен unixODBC, потому что бэкенд импортирует pyodbc при загрузке Django. Вам не нужен репозиторий пакетов Microsoft или msodbcsql18, поэтому блок установки ODBC сжимается до:

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

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

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

Используйте 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"
            ]
        }
    }
}

Этот devcontainer устанавливает драйвер ODBC для стандартного пути pyodbc и зависимостей Python, но не включает экземпляр SQL Server. Запустите его внутри devcontainer с помощью sqlcmd create mssql --accept-eula (так как Docker-in-Docker доступен) или используйте подход Docker Compose для встроенной службы SQL Server. Если вы используете вариант с mssql-python, замените команду установки msodbcsql18 в скрипте post-create на sudo apt-get install -y unixodbc libkrb5-3 libgssapi-krb5-2.

Создайте .devcontainer/post-create.sh для установки драйвера ODBC для зависимостей pyodbc и 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: "<strong_password>"
    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"] при использовании pyodbc, либо параметр 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": "<server>.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": "<server>.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: "<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

Для общих конвейеров замените встроенный пароль заполнителя зашифрованным секретом (${{ 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: "<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 на основе переменных среды

Настройте 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=<user_id>
DB_PASSWORD=<password>

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

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

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

Симптом Причина Исправление
Can't open lib 'ODBC Driver 18 for SQL Server' Драйвер ODBC не был установлен в контейнере для пути pyodbc или apt-get autoremove снят libgssapi-krb5-2 после установки. Установите msodbcsql18 в Dockerfile или в скрипт, выполняемый после создания, и после этого не запускайте apt-get autoremove.
Can't open lib 'ODBC Driver 17 for SQL Server' Когда вы установили версию 18 Версия 18 зарегистрирована, но не загружается, поэтому mssql-django возвращается к версии 17, которая не установлена. Обычная причина — отсутствует libgssapi-krb5-2. Установите libgssapi-krb5-2и не запускайте apt-get autoremove после очистки curl.
Error loading pyodbc module: libodbc.so.2 В контейнере нет unixODBC runtime. Бэкенд импортирует pyodbc при загрузке Django, даже по пути mssql-python. Установить unixodbc (или unixodbc-dev).
DDBC Error: Failed to load the driver Драйвер mssql-python не может загружать собственные зависимости. Установка libkrb5-3 и libgssapi-krb5-2.
Подключение отказано через порт 1433 SQL Server контейнер не готов. Добавьте проверку работоспособности или дождитесь запуска службы.
Login failed for user '<user_id>' Учетные данные неверны или пароль не соответствуют требованиям сложности. На пути mssql-python несуществующая база данных вызывает то же самое сообщение. Используйте правильное имя входа SQL для контейнера и убедитесь, что пароль соответствует требованиям сложности. Если логин верен, убедитесь, что база данных в NAME существует.
Cannot open database База данных еще не существует. Путь pyodbc сообщает об этом случае; а путь mssql-python вместо этого сообщает о Login failed. Создайте базу данных перед запуском migrateили используйте master для начальной настройки.
Медленное первое подключение в контейнере Разрешение DNS или запуск цепочки учетных данных. Для локальной SQL Server используйте localhost вместо имени узла.
SSL Provider: [error:0A000086] Сбой проверки TLS-сертификата при использовании самоподписанного сертификата. Добавьте TrustServerCertificate=yes в extra_params только для разработки.