Sviluppo di container e locale con mssql-python

Questa guida copre la configurazione dell'ambiente per sviluppatori Python che lavorano con il mssql-python driver su Windows, Linux, macOS, container Docker, devcontainer e pipeline CI.

Prerequisiti

  • Python 3.10 o versione successiva.
  • Docker Desktop (per lo sviluppo basato su container).
  • Un host compatibile con x64 (Intel, AMD o VM x64) per container Linux SQL Server. I container Linux di SQL Server non supportano host ARM64.

L'utilità go-sqlcmd può creare un container SQL Server in un unico comando. Gestisce automaticamente il pull dell'immagine Docker, la generazione di password, l'assegnazione di porte e il contesto di connessione:

sqlcmd create mssql --accept-eula

Per creare un contenitore con un database di esempio già collegato:

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

Dopo la creazione, sqlcmd archivia il contesto di connessione in modo da poter eseguire immediatamente una query:

sqlcmd query "SELECT @@VERSION"

Crea un accesso dell'applicazione una sola volta, quindi usalo nel tuo codice 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>;"

Sostituisci <database>, <app-login>, e <password> con valori provenienti dal tuo ambiente.

Connettiti da Python usando i dettagli di connessione stampati da sqlcmd al momento della creazione. Usare sqlcmd config view per recuperarli in un secondo momento:

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

Una volta terminato, arrestare o eliminare il container:

sqlcmd stop
sqlcmd delete

Tip

Eseguire sqlcmd create mssql --user-database <database> per creare un contenitore con un database utente vuoto pronto per lo sviluppo.

Local SQL Server da VS Code

L'estensione SQL Server per VS Code (ms-mssql.mssql) può creare container SQL Server locali direttamente dall'editor:

  1. Aprire la visualizzazione SQL Server nella barra delle attività.
  2. Selezionare Aggiungi connessione>Crea SQL Server locale oppure usare il riquadro comandi MS SQL: Crea SQL Server locale.
  3. Scegliere la versione SQL Server e accettare il contratto di licenza.
  4. L'estensione esegue il pull dell'immagine del contenitore, genera una password e aggiunge automaticamente un profilo di connessione.

Una volta che il container è in funzione, puoi navigare nei database, eseguire query e gestire oggetti direttamente in VS Code prima di passare al codice Python.

SQL Server locale con Docker

Se si preferisce gestire direttamente i contenitori, l'immagine ufficiale del contenitore SQL Server funziona con due variabili di 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

Aspetta qualche secondo, poi connettiti da 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

Usare MSSQL_SA_PASSWORD per i contenitori SQL Server. La variabile precedente SA_PASSWORD è deprecata. La password deve soddisfare SQL Server requisiti di complessità: almeno 8 caratteri, con caratteri maiuscoli, minuscoli, cifre e caratteri speciali.

Per caricare il database di campioni di AdventureWorks nel container:

# 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

L'approccio sqlcmd create mssql --using della sezione precedente gestisce automaticamente il download e il ripristino.

Dockerfile per applicazioni Python

Mantieni il riferimento all’immagine di base di Python in un unico posto, in modo che le build locali, i devcontainer e le pipeline CI non si disallineino. Per la sperimentazione locale, un tag ampiamente supportato come python:3-slim funziona bene. Per i devcontainer condivisi, la CI e gli ambienti di produzione, sostituisci quel tag con un'immagine approvata bloccata tramite digest dall'elenco degli elementi consentiti della tua organizzazione.

Crea un file Docker minimo per un'applicazione Python che si connette a 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"]

Il tuo requirements.txt:

mssql-python>=1.11.0

Compilare ed eseguire:

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

Negli ambienti condivisi, fornire con --build-arg PYTHON_BASE=python:3-slim@sha256:<approved-digest> un riferimento approvato a un'immagine di base immutabile.

Note

Usare host.docker.internal in Docker Desktop (Windows e macOS) per raggiungere un SQL Server nel computer host. In Linux usare --network host invece .

Alpine Linux

Alpine usa musl invece di glibc. Installare i pacchetti necessari:

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

Configurazione di Devcontainer

Riutilizza lo stesso Dockerfile con cui la tua applicazione compila. Questo approccio mantiene il devcontainer allineato con la tua immagine runtime e impedisce la diffusione dei pin della versione Python su più file.

Crea un .devcontainer/devcontainer.json per 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"
            ]
        }
    }
}

Per includere SQL Server come servizio in devcontainer, usare 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 (Versione 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"
            ]
        }
    }
}

Per gli spazi di lavoro condivisi, fissa l'immagine del servizio SQL Server a un digest approvato invece di affidarti a un tag fluttuante. Carica MSSQL_SA_PASSWORD da un file locale .env o da un archivio dei segreti della piattaforma invece di archiviarlo nel controllo del codice sorgente.

Connettiti al servizio SQL Server per nome:

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

Dipendenze specifiche della piattaforma

Il mssql-python driver raggruppa i suoi componenti nativi. Non è necessario installare un gestore driver ODBC esterno. Tuttavia, il driver richiede un piccolo insieme di librerie di sistema su Linux e macOS.

Platform Pacchetti obbligatori Installa comando
Windows None Inclusi nella ruota.
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 (tramite Homebrew) brew install openssl

Per macOS, se incontri errori SSL, imposta i linker flag:

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

Per le istruzioni complete di installazione, vedi Installa mssql-python.

Autenticazione per lo sviluppo

Sviluppo locale con Azure SQL

Usa ActiveDirectoryDefault per l'autenticazione senza password. Questa opzione si concatena automaticamente tramite interfaccia della riga di comando di Azure, Visual Studio, variabili di ambiente e identità gestita:

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

Assicurati di essere connesso usando interfaccia della riga di comando di Azure:

az login

Sviluppo locale contro SQL Server

Usa l'autenticazione SQL con un'istanza locale.

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

Sviluppo di contenitori con Azure SQL

Per i container che girano in Azure (App Service, Container Apps, AKS), usa l'identità gestita.

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

Per i container che girano localmente e devono connettersi ad Azure SQL, assicurati che il container abbia una sorgente di credenziali che ActiveDirectoryDefault possa essere utilizzata. Le opzioni più affidabili sono:

  • Installa interfaccia della riga di comando di Azure nel container e accedi lì. Monta ~/.azure dall'host solo se l'immagine del container include già interfaccia della riga di comando di Azure e intendi riutilizzare quella cache delle credenziali.
  • Fornire le credenziali dell'entità servizio tramite variabili di ambiente come AZURE_CLIENT_ID, AZURE_TENANT_ID e AZURE_CLIENT_SECRET.

Poi usa ActiveDirectoryDefault nel tuo codice di connessione.

Endpoint Microsoft SQL supportati

Il mssql-python driver si collega a tutti gli endpoint Microsoft SQL:

Punto finale Authentication
SQL Server (on-premises o in una VM) Autenticazione SQL, autenticazione Windows
Database SQL di Microsoft Azure Microsoft Entra ID (consigliato), autenticazione SQL
Istanza gestita di SQL di Azure (Istanza gestita di Azure SQL) Microsoft Entra ID (consigliato), autenticazione SQL
Azure Synapse Analytics (pool dedicati) Microsoft Entra ID, autenticazione SQL
Database SQL nell'ambiente Fabric Microsoft Entra ID
Fabric Data Warehouse Microsoft Entra ID
Endpoint di analisi SQL (Lakehouse) Microsoft Entra ID
Endpoint di analisi SQL (database con mirroring) Microsoft Entra ID

Vedi l'autenticazione Microsoft Entra per tutte e sette le modalità di autenticazione e il ciclo di vita del Supporto per la matrice completa di compatibilità.

Configurazione della pipeline CI

GitHub Actions

Tieni il runtime Python in una sola variabile così puoi rivedere e aggiornarlo in un unico posto. Usa 3.x per pipeline di validazione rapide, oppure sostituiscilo con una versione esatta approvata dall'organizzazione per le pipeline di rilascio.

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

Per le pipeline condivise, sostituisci la password segnaposto in linea con un segreto crittografato, blocca l'immagine del servizio SQL Server su un digest e mantieni la versione di Python in una variabile gestita dall'organizzazione o in un input di un workflow riutilizzabile.

Azure Pipelines

Usa una risorsa container per eseguire SQL Server come servizio insieme al tuo lavoro di test:

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

Come per GitHub Actions, sostituisci la password del segnaposto inline con una variabile segreta prima di usare questo pattern al di fuori di una pipeline demo usa e getta.

Sicurezza e segreti

Non codificare rigidamente password di database o stringhe di connessione nel codice sorgente o nei file Docker. Usa invece variabili ambientali e gestione dei segreti.

Variabili ambientali per lo sviluppo locale

Archivia le credenziali nelle variabili di ambiente o in un file .env escluso dal controllo della versione:

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

Per Docker Compose, fare riferimento a un file .env:

services:
  app:
    build: .
    env_file: .env

Attenzione

Non eseguire mai il commit dei .env file nel controllo del codice sorgente. Aggiungere .env nel .gitignore file.

Segreti CI/CD

Nelle pipeline CI, si utilizza lo storage segreto della piattaforma invece delle variabili di ambiente in chiaro:

Igiene della catena di approvvigionamento dei container

Usa queste pratiche per ambienti di sviluppo condivisi e CI:

  • Tieni i riferimenti delle immagini in un unico posto, come un Docker ARG, una build di devcontainer o una variabile pipeline.
  • Blocca le immagini di container condivise su digest immutabili invece che su tag variabili.
  • Rivedi e aggiorna i digest fissati tramite un processo di aggiornamento approvato come Dependabot, Renovate o un flusso di lavoro interno di promozione delle immagini.
  • Effettua commit di un file di blocco di dipendenza come uv.lock, oppure usa file di requisiti hashati per installazioni riproducibili in Python.
  • Preferisci immagini base approvate dall'organizzazione e specchi interni del registro quando la tua piattaforma li fornisce.

Produzione: autenticazione senza password

Per carichi di lavoro di produzione su Azure SQL, usa l'autenticazione Microsoft Entra con identità gestita. Questo approccio elimina completamente le password:

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

Per le applicazioni che necessitano di memorizzare segreti come password di autenticazione SQL, usa Azure Key Vault e recuperali in runtime.

Gestione delle dipendenze con uv

UV è un installatore rapido di pacchetti Python che funziona bene in build CI e container:

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

In CI:

pip install uv
uv sync
uv run pytest

Risolvere i problemi comuni relativi ai contenitori

Sintomo Cause Correzione
ImportError: libltdl.so.7 Libreria di sistema mancante. Installa libltdl7 (Debian) o libltdl (Alpine).
ImportError: libkrb5.so.3 Biblioteca di Kerberos mancante. Installa libkrb5-3 (Debian) o krb5-libs (Alpine/RHEL).
SSL: CERTIFICATE_VERIFY_FAILED Certificato autofirmato su SQL Server locale. Aggiungi trust_server_certificate="yes" alla connessione. Non usarlo in produzione.
Connessione rifiutata sulla porta 1433 SQL Server contenitore non pronto. Aggiungere un controllo integrità o attendere l'avvio del servizio.
Login failed for user 'sa' La password non soddisfa i requisiti di complessità. Usa una password con maiuscolo, minuscolo, cifre e caratteri speciali.
Cannot open database Il database non esiste ancora. Crea o ripristina il database prima di connetterti.
Prima connessione lenta nel container Avvio della risoluzione DNS o della catena di credenziali. Per SQL Server locale, usa localhost,1433 invece di nome host. Per Azure SQL, eseguire l'autenticazione preventiva con az login.