Desenvolvimento em contêiner e local com mssql-python

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

Pré-requisitos

  • Python 3.10 ou posterior.
  • Docker Desktop (para desenvolvimento baseado em container).
  • Um host compatível com x64 (Intel, AMD ou VM x64) para contêineres Linux do SQL Server. Os contêineres Linux do SQL Server não suportam hosts ARM64.

A utilitária go-sqlcmd 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"

Crie um login de aplicativo uma vez e depois use no seu código 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>;"

Substitua <database>, <app-login>, e <password> por valores do seu ambiente.

Conecte-se usando Python com os detalhes da conexão que sqlcmd exibiu durante a criação. Use sqlcmd config view para recuperá-los mais tarde:

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()

Quando terminar, pare ou exclua o contêiner:

sqlcmd stop
sqlcmd delete

Tip

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

Servidor SQL local no VS Code

A extensão SQL Server para VS Code (ms-mssql.mssql) pode criar contêineres 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 container está rodando, você pode navegar por bancos de dados, rodar consultas e gerenciar objetos diretamente no VS Code antes de mudar para código Python.

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

Espere alguns segundos e então conecte pelo 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()

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.

Para carregar o banco de dados de exemplos do AdventureWorks no contêiner:

# 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

A sqlcmd create mssql --using abordagem da seção anterior gerencia o download e a restauração automaticamente.

Dockerfile para aplicações Python

Mantenha a referência da imagem base em Python em um só lugar para que builds locais, devcontainers e pipelines de CI não se desviem. Para experimentação local, uma tag ampla e suportada como python:3-slim funciona bem. Para devcontainers compartilhados, CI e produção, substitua essa tag por uma imagem aprovada fixada no digest da lista de permissões da sua organização.

Crie um arquivo Docker mínimo para um aplicativo Python que se conecte ao 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"]

Seu requirements.txt:

mssql-python>=1.11.0

Compilar e executar:

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

Em ambientes compartilhados, passe uma referência de imagem base imutável aprovada com --build-arg PYTHON_BASE=python:3-slim@sha256:<approved-digest>.

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.

Linux alpino

Alpine usa musl em vez de glibc. Instale os pacotes necessários:

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

Configuração do Devcontainer

Reutilize o mesmo Dockerfile com o qual seu aplicativo compila. Essa abordagem mantém o devcontainer alinhado com sua imagem de runtime e evita espalhar os pins da versão Python por múltiplos arquivos.

Crie um .devcontainer/devcontainer.json para o 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"
            ]
        }
    }
}

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

Para espaços de trabalho compartilhados, fixe a imagem do serviço do SQL Server em um digest aprovado em vez de depender de uma tag flutuante. Carregue MSSQL_SA_PASSWORD de um arquivo local .env ou de um armazenamento secreto da plataforma em vez de registrar no controle de versão.

Conecte-se ao serviço SQL Server pelo nome:

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

Dependências específicas de plataforma

O driver mssql-python inclui seus componentes nativos. Você não precisa instalar um gerenciador externo de drivers ODBC. No entanto, o driver requer um pequeno conjunto de bibliotecas de sistema no Linux e macOS.

Platform Pacotes necessários Comando de Instalação
Windows None Incluído na roda.
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
Alpine libltdl, krb5-libs apk add libltdl krb5-libs
macOS OpenSSL (via Homebrew) brew install openssl

Para macOS, se você encontrar erros SSL, defina as bandeiras de linker:

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

Para instruções completas de instalação, veja Instalar mssql-python.

Autenticação para desenvolvimento

Desenvolvimento local contra SQL do Azure

Use ActiveDirectoryDefault para autenticação sem senha. Essa opção se encadeia automaticamente através do CLI do Azure, Visual Studio, variáveis de ambiente e identidade gerenciada:

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

Certifique-se de estar logado usando a CLI do Azure:

az login

Desenvolvimento local contra SQL Server

Use autenticação SQL com uma instância local.

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

Desenvolvimento de contêiner em SQL do Azure

Para contêineres rodando no Azure (App Service, Container Apps, AKS), use identidade gerenciada.

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

Para containers em execução local que precisam se conectar ao SQL do Azure, certifique-se de que o container tenha uma origem de credenciais que ActiveDirectoryDefault possa usar. As opções mais confiáveis são:

  • Instale a CLI do Azure no container e faça login lá. Monte ~/.azure a partir do host somente se a imagem do container já incluir CLI do Azure e você pretende reutilizar esse cache de credencial.
  • Forneça credenciais de principal de serviço por meio de variáveis de ambiente como AZURE_CLIENT_ID, AZURE_TENANT_ID, e AZURE_CLIENT_SECRET.

Depois, use ActiveDirectoryDefault em seu código de conexão.

Endpoints do Microsoft SQL suportados

O mssql-python driver conecta a todos os endpoints SQL do Microsoft:

Endpoint Authentication
SQL Server (on-premises ou em uma VM) Autenticação SQL, autenticação do Windows
Banco de Dados SQL do Azure Microsoft Entra ID (recomendado), autenticação SQL
Instância Gerenciada de SQL do Azure Microsoft Entra ID (recomendado), autenticação SQL
Azure Synapse Analytics (pools dedicados) Microsoft Entra ID, autenticação SQL
Banco de dados SQL no Fabric Microsoft Entra ID
Armazém de Dados Fabric Microsoft Entra ID
Endpoint de análise SQL (Lakehouse) Microsoft Entra ID
Endpoint de análise SQL (banco de dados espelhado) Microsoft Entra ID

Veja a autenticação Microsoft Entra para todos os sete modos de autenticação e o ciclo de vida de suporte para a matriz completa de compatibilidade.

Configuração do pipeline de CI

GitHub Actions

Mantenha o runtime em Python em uma única variável para que você possa revisá-lo e atualizá-lo em um só lugar. Use 3.x para pipelines de validação rápidos, ou substitua por uma versão exata aprovada pela organização para pipelines de release.

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

Para pipelines compartilhados, substitua a senha provisória inline por um segredo criptografado, fixe a imagem do serviço SQL Server em um resumo e mantenha a versão Python em uma variável gerenciada pela organização ou entrada de fluxo de trabalho reutilizável.

Azure Pipelines

Use um recurso container para rodar o SQL Server como um serviço junto com seu trabalho de teste:

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

Assim como no GitHub Actions, substitua a senha provisória inline por uma variável secreta antes de usar esse padrão fora de um pipeline de demonstração descartável.

Segurança e segredos

Não codifique senhas de banco de dados ou strings de conexão no código-fonte ou no Dockerfiles. Use variáveis de ambiente e gerenciamento de segredos em vez disso.

Variáveis ambientais para desenvolvimento local

Armazene credenciais em variáveis de ambiente ou em um .env arquivo excluído do controle de versão:

# .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"
)

Para o Docker Compose, consulte o arquivo .env:

services:
  app:
    build: .
    env_file: .env

Cuidado

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

Segredos de CI/CD

Em pipelines de CI, use o armazenamento secreto da plataforma em vez de variáveis de ambiente em texto simples:

Higiene da cadeia de suprimentos de contêineres

Use essas práticas para ambientes compartilhados de desenvolvedores e CI:

  • Mantenha as referências de imagem em um só lugar, como um arquivo Docker ARG, uma compilação de devcontainer ou uma variável de pipeline.
  • Fixe imagens de contêineres compartilhadas em digests imutáveis em vez de tags flutuantes.
  • Revise e atualize os resumos fixados por meio de um processo de atualização aprovado, como Dependabot, Renovate ou um fluxo interno de promoção de imagens.
  • Commit um arquivo de bloqueio de dependência como uv.lock, ou use arquivos de requisitos com hash para instalações reproduzíveis em Python.
  • Prefira imagens de base aprovadas pela organização e espelhos internos do registro quando sua plataforma os fornecer.

Produção: autenticação sem senha

Para cargas de produção contra SQL do Azure, use autenticação Microsoft Entra com identidade gerenciada. Essa abordagem elimina completamente as senhas:

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

Para aplicações que precisam armazenar segredos, como senhas de autenticação SQL, use o Azure Key Vault e recupere-as em tempo de execução.

Gerenciamento de dependências com uv

UV é um instalador rápido de pacotes Python que funciona bem em builds de CI e containers:

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

Em CI:

pip install uv
uv sync
uv run pytest

Solucionar problemas comuns de contêiner

Sintoma Cause Corrigir
ImportError: libltdl.so.7 Biblioteca do sistema ausente. Instale libltdl7 (Debian) ou libltdl (Alpine).
ImportError: libkrb5.so.3 Biblioteca Kerberos ausente. Instalar libkrb5-3 (Debian) ou krb5-libs (Alpine/RHEL).
SSL: CERTIFICATE_VERIFY_FAILED Certificado autoassinado no SQL Server local. Adicione trust_server_certificate="yes" à conexão. Não use isso na produçã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 'sa' A senha não atende aos requisitos de complexidade. Use uma senha com maiúsculas, minúsculas, dígitos e caracteres especiais.
Cannot open database O banco de dados ainda não existe. Crie ou restaure o banco de dados antes de conectar.
Primeira conexão lenta no contêiner Resolução de DNS ou inicialização da cadeia de credenciais. Para SQL Server local, use localhost,1433 em vez de nome de host. Para SQL do Azure, faça a pré-autenticação com az login.