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

Это руководство охватывает настройку среды для разработчиков Python, работающих с драйвером mssql-python в контейнерах Windows, Linux, macOS, Docker, devcontainers и CI-конвейерах.

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

  • Python 3.10 или более поздней версии.
  • Docker Desktop (для контейнерной разработки).
  • Совместимый с x64 хост (Intel, AMD или x64 VM) для контейнеров Linux на SQL Server. Контейнеры Linux SQL Server не поддерживают ARM64-хосты.

Утилита go-sqlcmd может создавать контейнер SQL Server в одной команде. Он автоматически обрабатывает извлечение образа Docker, создание паролей, назначение порта и контекст подключения:

sqlcmd create mssql --accept-eula

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

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

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

sqlcmd query "SELECT @@VERSION"

Создайте логин приложения один раз, а затем используйте его в своём коде на Python:

sqlcmd query --database <database> "CREATE LOGIN <app-login> WITH PASSWORD = '<password>';"
sqlcmd query --database <database> "CREATE USER <app-login> FOR LOGIN <app-login>;"
sqlcmd query --database <database> "ALTER ROLE db_datareader ADD MEMBER <app-login>;"
sqlcmd query --database <database> "ALTER ROLE db_datawriter ADD MEMBER <app-login>;"

Замените <database>, <app-login>, и <password> на значения из вашей среды.

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

import mssql_python

conn = mssql_python.connect(
    server="localhost,1433",
    uid="<app login>",
    pwd="<password>",
    encrypt="yes",
    trust_server_certificate="yes"
)

cursor = conn.cursor()
cursor.execute("SELECT @@VERSION")
print(cursor.fetchval())
conn.close()

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

sqlcmd stop
sqlcmd delete

Tip

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

Локальный SQL Server от VS Code

Расширение SQL Server для VS Code (ms-mssql.mssql) может создавать локальные контейнеры SQL Server непосредственно из редактора:

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

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

Локальный 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

Подождите несколько секунд, затем подключитесь через Python:

import mssql_python

conn = mssql_python.connect(
    server="localhost,1433",
    uid="<app login>",
    pwd="<password>",
    encrypt="yes",
    trust_server_certificate="yes"
)

cursor = conn.cursor()
cursor.execute("SELECT @@VERSION")
print(cursor.fetchval())
conn.close()

Important

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

Чтобы загрузить образцовую базу данных AdventureWorks в контейнер:

# Download AdventureWorks backup
curl -L -o AdventureWorks2022.bak \
  "https://github.com/Microsoft/sql-server-samples/releases/download/adventureworks/AdventureWorks2022.bak"

# Copy into container
docker cp AdventureWorks2022.bak sql1:/var/opt/mssql/backup/

# Restore
docker exec sql1 /opt/mssql-tools18/bin/sqlcmd \
  -S localhost -U sa -P "YourStr0ngP@ssword" -C \
  -Q "RESTORE DATABASE AdventureWorks2022 FROM DISK='/var/opt/mssql/backup/AdventureWorks2022.bak' WITH MOVE 'AdventureWorks2022' TO '/var/opt/mssql/data/AdventureWorks2022.mdf', MOVE 'AdventureWorks2022_log' TO '/var/opt/mssql/data/AdventureWorks2022_log.ldf'"

Tip

Подход, sqlcmd create mssql --using описанный в предыдущем разделе, автоматически осуществляет загрузку и восстановление.

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

Храните ссылку на базовый образ Python в одном месте, чтобы локальные сборки, контейнеры разработки и CI-конвейеры не расходились. Для локальных экспериментов хорошо подходит широко поддерживаемый тег, например python:3-slim. Для общих контейнеров разработки, CI и продакшна замените этот тег на одобренный дайджест-прикреплённый образ из списка разрешений вашей организации.

Создайте минимальный Dockerfile для Python-приложения, которое подключается к Microsoft SQL:

ARG PYTHON_BASE=python:3-slim
FROM ${PYTHON_BASE}

# Install system libraries required by mssql-python on Linux
RUN apt-get update && \
    apt-get install -y --no-install-recommends libltdl7 libkrb5-3 libgssapi-krb5-2 && \
    rm -rf /var/lib/apt/lists/*

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

COPY . .
CMD ["python", "app.py"]

Ваш requirements.txt:

mssql-python>=1.11.0

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

docker build -t myapp .
docker run -e SQL_SERVER=host.docker.internal,1433 myapp

В средах с общим доступом указывайте ссылку на одобренный неизменяемый базовый образ с помощью --build-arg PYTHON_BASE=python:3-slim@sha256:<approved-digest>.

Замечание

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

Alpine Linux

Alpine использует musl вместо glibc. Установите необходимые пакеты:

ARG PYTHON_BASE=python:3-alpine
FROM ${PYTHON_BASE}

RUN apk add --no-cache libltdl krb5-libs

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

COPY . .
CMD ["python", "app.py"]

Настройка Devcontainer

Используйте тот же Dockerfile, с которым строится ваше приложение. Такой подход поддерживает выровняние devcontainer с вашим образом выполнения и предотвращает разбросывание пинов версии Python между несколькими файлами.

Создайте .devcontainer/devcontainer.json для VS Code:

{
    "name": "Python + SQL Server",
    "build": {
        "dockerfile": "../Dockerfile",
        "context": ".."
    },
    "features": {
        "ghcr.io/devcontainers/features/docker-in-docker:2": {}
    },
    "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
    "postCreateCommand": "pip install --no-cache-dir -r requirements.txt",
    "forwardPorts": [1433],
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-mssql.mssql"
            ]
        }
    }
}

Чтобы включить SQL Server в качестве службы в devcontainer, используйте Docker Compose:

.devcontainer/docker-compose.yml:

services:
  app:
    build:
      context: ..
      dockerfile: Dockerfile
    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": "Python + SQL Server",
    "dockerComposeFile": "docker-compose.yml",
    "service": "app",
    "workspaceFolder": "/workspace",
    "postCreateCommand": "pip install -r requirements.txt",
    "customizations": {
        "vscode": {
            "extensions": [
                "ms-python.python",
                "ms-mssql.mssql"
            ]
        }
    }
}

Для общих рабочих пространств закрепляйте образ сервиса SQL Server к утверждённому дайджесту вместо того, чтобы полагаться на плавающий тег. Загружайте MSSQL_SA_PASSWORD из локального .env файла или секретного хранилища платформы, вместо того чтобы проверять их в систему контроля версий.

Подключитесь к сервису SQL Server по названию:

conn = mssql_python.connect(
    server="db,1433",
    uid="<app login>",
    pwd="<password>",
    encrypt="yes",
    trust_server_certificate="yes"
)

Зависимости, специфичные для платформы

Драйвер mssql-python объединяет свои собственные компоненты. Вам не нужно устанавливать внешний диспетчер драйверов ODBC. Однако для драйвера требуется небольшой набор системных библиотек на Linux и macOS.

Платформа Обязательные пакеты Команда установки
Windows Нет Входит в комплект колеса.
Ubuntu / Debian libltdl7, libkrb5-3, libgssapi-krb5-2 sudo apt-get install libltdl7 libkrb5-3 libgssapi-krb5-2
Red Hat / CentOS / Fedora libtool-ltdl, krb5-libs sudo dnf install libtool-ltdl krb5-libs
Алпайн libltdl, krb5-libs apk add libltdl krb5-libs
macOS OpenSSL (через Homebrew) brew install openssl

Для macOS, если вы столкнётесь с ошибками SSL, установите флаги linker:

export LDFLAGS="-L/opt/homebrew/opt/openssl/lib"
export CPPFLAGS="-I/opt/homebrew/opt/openssl/include"

Для полных инструкций по установке см. Установить mssql-python.

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

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

Используйте ActiveDirectoryDefault для аутентификации без пароля. Этот вариант автоматически объединяется через Azure CLI, Visual Studio, переменные среды и управляемую идентичность:

conn = mssql_python.connect(
    server="<server>.database.windows.net",
    database="<database>",
    authentication="ActiveDirectoryDefault",
    encrypt="yes"
)

Убедитесь, что вы вошли в систему, используя Azure CLI:

az login

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

Используйте SQL аутентификацию с локальным экземпляром.

conn = mssql_python.connect(
    server="localhost,1433",
    uid="<app login>",
    pwd="<password>",
    encrypt="yes",
    trust_server_certificate="yes"
)

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

Для контейнеров, работающих в Azure (App Service, Container Apps, AKS), используйте управляемую идентичность.

conn = mssql_python.connect(
    server="<server>.database.windows.net",
    database="<database>",
    authentication="ActiveDirectoryMSI",
    encrypt="yes"
)

Для контейнеров, запущенных локально и необходимых подключения к Azure SQL, убедитесь, что контейнер имеет источник учетных данных, который ActiveDirectoryDefault может использовать. Самые надёжные варианты:

  • Установите Azure CLI в контейнер и войдите там. Монтируйте ~/.azure с хоста только если образ контейнера уже содержит Azure CLI и вы планируете повторно использовать этот кэш учетных данных.
  • Укажите учетные данные субъекта-службы с помощью переменных среды, таких как AZURE_CLIENT_ID, AZURE_TENANT_ID и AZURE_CLIENT_SECRET.

Затем используйте ActiveDirectoryDefault в коде подключения.

Поддерживаемые Microsoft SQL конечные точки

mssql-python Драйвер подключается ко всем конечным точкам Microsoft SQL:

Endpoint Authentication
SQL Server (локально или в виртуальной машине) проверка подлинности SQL, проверка подлинности Windows
База данных SQL Azure Microsoft Entra ID (рекомендовано), аутентификация SQL
Управляемый экземпляр Azure SQL Microsoft Entra ID (рекомендовано), аутентификация SQL
Azure Synapse Analytics (выделенные пулы) Microsoft Entra ID, аутентификация SQL
База данных SQL в Fabric Майкрософт Ентра айди
Хранилище данных Fabric Майкрософт Ентра айди
Конечная точка аналитики SQL (Lakehouse) Майкрософт Ентра айди
Конечная точка аналитики SQL (зеркальной базы данных) Майкрософт Ентра айди

См. аутентификация Microsoft Entra для всех семи режимов аутентификации и жизненный цикл поддержки для полной матрицы совместимости.

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

GitHub Actions

Держите время выполнения Python в одной переменной, чтобы можно было просматривать и обновлять её в одном месте. Используйте 3.x для быстро меняющихся валидационных конвейеров или замените их на точную версию, одобренную организацией для релизных конвейеров.

name: Test with SQL Server
on: [push, pull_request]

env:
  PYTHON_VERSION: "3.x"

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 YourStr0ngP@ssword -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: ${{ env.PYTHON_VERSION }}
          check-latest: true

      - name: Install dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y libltdl7 libkrb5-3 libgssapi-krb5-2
          pip install -r requirements.txt

      - name: Run tests
        env:
          SQL_SERVER: localhost,1433
          SQL_UID: sa
          SQL_PWD: YourStr0ngP@ssword
        run: pytest

Для общих конвейеров замените встроенный пароль на зашифрованный секрет, закрепите образ сервиса SQL Server на дайджесте и оставьте версию Python в переменной, управляемой организацией, или в повторно используемом рабочем процессе.

Azure Pipelines

Используйте контейнерный ресурс для запуска SQL Server как сервиса вместе с вашим тестовым заданием:

trigger:
  - main

variables:
  python.version: "3.x"

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: "$(python.version)"

  - script: |
      sudo apt-get update
      sudo apt-get install -y libltdl7 libkrb5-3 libgssapi-krb5-2
      pip install -r requirements.txt
    displayName: Install dependencies

  - script: pytest
    displayName: Run tests
    env:
      SQL_SERVER: localhost,1433
      SQL_UID: sa
      SQL_PWD: YourStr0ngP@ssword

Как и в GitHub Actions, замените встроенный пароль на секретную переменную перед использованием этого шаблона вне одноразового демо-пайплайна.

Безопасность и секреты

Не закодуйте пароли баз данных или строки подключения в исходном коде или Dockerfiles. Используйте переменные среды и управление секретами.

Переменные окружающей среды для локального развития

Храните учетные данные в переменных среды или в .env файле, исключённом из контроля исходного кода:

# .env (add to .gitignore)
SQL_SERVER=localhost,1433
SQL_UID=sa
SQL_PWD=YourStr0ngP@ssword
import os
import mssql_python

conn = mssql_python.connect(
    server=os.environ["SQL_SERVER"],
    uid=os.environ["SQL_UID"],
    pwd=os.environ["SQL_PWD"],
    encrypt="yes",
    trust_server_certificate="yes"
)

Для Docker Compose укажите файл .env:

services:
  app:
    build: .
    env_file: .env

Предостережение

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

Секреты CI/CD

В CI-конвейерах используйте секретное хранилище платформы вместо открытых переменных среды:

Гигиена цепочки поставок в контейнерах

Используйте эти практики для общих сред разработчиков и CI:

  • Храните ссылки на образы в одном месте, например, в Docker ARG, в сборке devcontainer или в переменной конвейера.
  • Pin делился изображениями контейнеров в неизменяемые дайджесты вместо плавающих тегов.
  • Просматривайте и обновляйте закреплённые дайджесты через одобренный процесс обновления, такой как Dependabot, Renovate или внутренний рабочий процесс продвижения изображений.
  • Зафиксируйте файл блокировки зависимостей, например uv.lock, или используйте хэшированные файлы требований для воспроизводимых установок на Python.
  • Предпочитайте одобренные организацией базовые изображения и внутренние зеркала реестра, когда ваша платформа их предоставляет.

Продакшн: аутентификация без пароля

Для производственных рабочих нагрузок против Azure SQL используйте аутентификацию Microsoft Entra с управляемой идентификацией. Этот подход полностью исключает пароли:

conn = mssql_python.connect(
    server="<server>.database.windows.net",
    database="<database>",
    authentication="ActiveDirectoryMSI",
    encrypt="yes"
)

Для приложений, которым нужно хранить секреты, такие как пароли SQL, используйте Azure Key Vault и извлекайте их во время выполнения.

Управление зависимостью с помощью UV

uv — это быстрый установщик пакетов на Python, который хорошо работает в CI и контейнерных сборках:

ARG PYTHON_BASE=python:3-slim
FROM ${PYTHON_BASE}

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

# Install uv. In shared builds, pin the source image to an approved digest.
COPY --from=ghcr.io/astral-sh/uv:latest /uv /usr/local/bin/uv

WORKDIR /app
COPY pyproject.toml uv.lock ./
RUN uv sync --frozen --no-dev

COPY . .
CMD ["uv", "run", "python", "app.py"]

В CI:

pip install uv
uv sync
uv run pytest

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

Симптом Причина Исправление
ImportError: libltdl.so.7 Отсутствует системная библиотека. Установка libltdl7 (Debian) или libltdl (Alpine).
ImportError: libkrb5.so.3 Пропала библиотека Kerberos. Установка libkrb5-3 (Debian) или krb5-libs (Alpine/RHEL).
SSL: CERTIFICATE_VERIFY_FAILED Самоподписанный сертификат на локальном SQL Server. Добавьте trust_server_certificate="yes" к соединению. Не используйте это в производстве.
Подключение отказано через порт 1433 SQL Server контейнер не готов. Добавьте проверку работоспособности или дождитесь запуска службы.
Login failed for user 'sa' Пароль не соответствует требованиям сложности. Используйте пароль с заглавными, строчными, цифрами и специальными символами.
Cannot open database База данных еще не существует. Создайте или восстановите базу данных перед подключением.
Медленное первое подключение в контейнере Разрешение DNS или запуск цепочки учетных данных. Для локального SQL Server используйте localhost,1433 вместо имени хоста. Для Azure SQL пройдите предварительную проверку подлинности с помощью az login.