Desenvolvimento em contêiner e local com mssql-django

Este guia aborda a configuração do ambiente para desenvolvedores do Django que trabalham com o mssql-django back-end em Windows, Linux, macOS, contêineres do Docker, devcontainers e pipelines de CI.

Pré-requisitos

  • Python 3.8 ou posterior (o Django 6.0 requer Python 3.12 e versões posteriores)
  • Área de Trabalho do Docker (para desenvolvimento baseado em contêiner)
  • Microsoft Driver ODBC 17 ou 18 para SQL Server. Consulte Baixar o Driver ODBC para SQL Server.

O utilitário sqlcmd (Go) pode criar um contêiner SQL Server em um único comando. Ele manipula automaticamente o pull de imagem do Docker, a geração de senha, a atribuição de porta e o contexto de conexão:

sqlcmd create mssql --accept-eula

Para criar um contêiner com um banco de dados de exemplo já anexado:

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

Após a criação, sqlcmd armazena o contexto de conexão para que você possa consultar imediatamente:

sqlcmd query "SELECT @@VERSION"

Configure o Django para se conectar usando os detalhes de conexão que sqlcmd exibiu durante a criação. Use sqlcmd config view para recuperá-los mais tarde:

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

Quando terminar, pare ou exclua o contêiner:

sqlcmd stop
sqlcmd delete

Tip

Execute sqlcmd create mssql --user-database mydb para criar um contêiner com um banco de dados de usuário vazio pronto para desenvolvimento.

SQL Server local em Visual Studio Code

A extensão MSSQL para Visual Studio Code pode criar contêineres de SQL Server locais diretamente do editor:

  1. Abra a exibição SQL Server na Barra de Atividades.
  2. Selecione Adicionar Conexão>Criar SQL Server Local (ou use a Paleta de Comandos: MS SQL: Criar SQL Server Local).
  3. Escolha a versão SQL Server e aceite o EULA.
  4. A extensão puxa a imagem de contêiner, gera uma senha e adiciona um perfil de conexão automaticamente.

Depois que o contêiner estiver em execução, você poderá procurar bancos de dados, executar consultas e gerenciar objetos em Visual Studio Code antes de alternar para o código do Django.

SQL Server local com o Docker

Se você preferir gerenciar contêineres diretamente, a imagem oficial do contêiner SQL Server funcionará com duas variáveis de ambiente:

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

Importante

Use MSSQL_SA_PASSWORD para contêineres de SQL Server. A variável mais antiga SA_PASSWORD foi preterida. A senha deve atender SQL Server requisitos de complexidade: pelo menos 8 caracteres, com letras maiúsculas, minúsculas, dígitos e caracteres especiais.

Aguarde alguns segundos para que o contêiner seja iniciado e execute as migrações:

python manage.py migrate
python manage.py createsuperuser

Dockerfile para aplicativos Django

Crie um Dockerfile mínimo para um aplicativo Django que se conecte a SQL Server. O driver ODBC é a dependência principal que não acompanha a imagem base do 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"]

Seu requirements.txt:

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

Compilar e executar:

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

Use host.docker.internal no Docker Desktop (Windows e macOS) para alcançar um SQL Server no computador host. No Linux, use --network host em vez disso.

Configuração do Devcontainer

Crie um .devcontainer/devcontainer.json para Visual Studio Code que inclua o SQL Server como um serviço 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"
            ]
        }
    }
}

Esse devcontainer instala o driver ODBC e Python dependências, mas não inclui uma instância SQL Server. Inicie um dentro do devcontainer usando sqlcmd create mssql --accept-eula (já que o Docker-in-Docker está disponível) ou use a abordagem do Docker Compose para um serviço de SQL Server interno.

Crie .devcontainer/post-create.sh para instalar o driver ODBC e as dependências do 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

Incluir o SQL Server com Docker Compose

Para incluir SQL Server como um serviço no devcontainer, use o 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 (versão do 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"
            ]
        }
    }
}

Conecte o Django ao serviço SQL Server pelo nome:

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

Autenticação para desenvolvimento

Escolha uma abordagem de autenticação com base no local em que seu aplicativo é executado e onde o banco de dados está hospedado.

Desenvolvimento local contra SQL do Azure

Para desenvolvimento local com o SQL do Azure, use Authentication=ActiveDirectoryDefault em OPTIONS["extra_params"] (com mssql-django 1.7.3 e posteriores, além de um Driver ODBC da Microsoft compatível) ou a configuração TOKEN com DefaultAzureCredential. DefaultAzureCredential retoma automaticamente sua az login sessão:

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

Para obter a matriz completa de autenticação e as advertências, consulte autenticação do Microsoft Entra com mssql-django.

Desenvolvimento de contêiner em SQL do Azure

Para contêineres em execução no Azure, use a configuração TOKEN com ManagedIdentityCredential para adquirir explicitamente um token de acesso do 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",
    },
  },
}

Para obter uma lista completa dos métodos de autenticação, consulte autenticação do Microsoft Entra com o mssql-django.

Configuração do pipeline de CI

Execute sua suíte de testes do Django usando um contêiner de serviço do SQL Server no pipeline de 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

Para pipelines compartilhados, substitua a senha placeholder embutida por um segredo criptografado (${{ secrets.SQL_PWD }}) e fixe a imagem do serviço SQL Server em um digest.

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 baseado no ambiente

Configure settings.py para ler credenciais de banco de dados a partir de variáveis de ambiente. Essa configuração única funciona em desenvolvimento local, Docker e 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"),
        },
    },
}

Armazenar credenciais em um .env arquivo para desenvolvimento local (adicione .env a .gitignore):

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

Carregar variáveis de ambiente com django-environ ou 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",
        },
    },
}

Cuidado

Nunca faça commit de arquivos .env no controle de versão. Adicione .env ao arquivo .gitignore.

Solucionar problemas comuns de contêiner

Sintoma Cause Corrigir
Can't open lib 'ODBC Driver 18 for SQL Server' Driver ODBC não instalado no contêiner. Instale msodbcsql18 no Dockerfile ou no script pós-criação.
Conexão recusada na porta 1433 SQL Server contêiner não está pronto. Adicione uma verificação de integridade ou aguarde o início do serviço.
Login failed for user '<username>' As credenciais estão incorretas ou a senha não atende aos requisitos de complexidade. Use o logon do SQL correto para o contêiner e verifique se a senha atende aos requisitos de complexidade.
Cannot open database O banco de dados ainda não existe. Crie o banco de dados antes de executar migrateou use master para a configuração inicial.
Primeira conexão lenta no contêiner Resolução de DNS ou inicialização da cadeia de credenciais. Para SQL Server locais, use localhost em vez de um nome de host.
SSL Provider: [error:0A000086] Falha de validação de certificado TLS com certificado autoassinado. Adicione TrustServerCertificate=yes a extra_params somente para desenvolvimento.