Rozwój kontenerowy i lokalny z MSSQL-Python

Ten przewodnik obejmuje konfigurację środowiska dla programistów Python pracujących z tym sterownikiem mssql-python na platformach Windows, Linux, macOS, kontenerach Docker, devcontainerach oraz potokach CI.

Wymagania wstępne

  • Python 3.10 lub nowszy.
  • Docker Desktop (do programowania opartego na kontenerach).
  • Host kompatybilny z x64 (Intel, AMD lub x64 VM) dla kontenerów SQL Server Linux. Kontenery SQL Server Linux nie obsługują hostów ARM64.

Narzędzie go-sqlcmd może utworzyć kontener SQL Server za pomocą jednego polecenia. Automatycznie obsługuje pobieranie obrazu Dockera, generowanie haseł, przypisywanie portów i kontekst połączenia:

sqlcmd create mssql --accept-eula

Aby utworzyć kontener z już dołączoną przykładową bazą danych:

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

Po utworzeniu sqlcmd przechowuje kontekst połączenia, dzięki czemu można od razu wykonywać zapytania:

sqlcmd query "SELECT @@VERSION"

Utworz zalogowanie do aplikacji raz, a następnie użyj go w swoim kodzie 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>;"

Zastąp <database>, <app-login>, i <password> wartościami ze swojego otoczenia.

Połącz się z poziomu Pythona, używając danych połączenia, które sqlcmd wyświetlił podczas tworzenia. Użyj polecenia sqlcmd config view, aby odzyskać je później:

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

Po zakończeniu zatrzymaj lub usuń kontener:

sqlcmd stop
sqlcmd delete

Wskazówka

Uruchom polecenie sqlcmd create mssql --user-database <database> , aby utworzyć kontener z pustą bazą danych użytkownika gotową do programowania.

Lokalny SQL Server z VS Code

Rozszerzenie SQL Server dla VS Code (ms-mssql.mssql) może tworzyć lokalne kontenery SQL Server bezpośrednio z edytora:

  1. Otwórz widok SQL Server na pasku działań.
  2. Wybierz pozycję Dodaj połączenie>Utwórz lokalne SQL Server (lub użyj palety poleceń: MS SQL: Utwórz lokalny SQL Server).
  3. Wybierz wersję SQL Server i zaakceptuj umowy EULA.
  4. Rozszerzenie ściąga obraz kontenera, generuje hasło i automatycznie dodaje profil połączenia.

Gdy kontener zacznie działać, możesz przeglądać bazy danych, uruchamiać zapytania i zarządzać obiektami bezpośrednio w VS Code, zanim przejdziesz na kod Python.

Lokalny SQL Server z Dockerem

Jeśli wolisz zarządzać kontenerami bezpośrednio, oficjalny obraz kontenera SQL Server działa z dwiema zmiennymi środowiskowymi:

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

Poczekaj kilka sekund, potem połącz się z 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

Użyj MSSQL_SA_PASSWORD w przypadku kontenerów SQL Server. Starsza SA_PASSWORD zmienna jest przestarzała. Hasło musi spełniać wymagania dotyczące złożoności SQL Server: co najmniej 8 znaków, z wielkimi literami, małymi literami, cyframi i znakami specjalnymi.

Aby załadować przykładową bazę danych AdventureWorks do kontenera:

# 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'"

Wskazówka

Podejście sqlcmd create mssql --using z poprzedniej sekcji automatycznie obsługuje pobieranie i przywracanie.

Dockerfile dla aplikacji Python

Trzymaj odniesienie do bazowego obrazu Python w jednym miejscu, żeby lokalne buildy, devcontainery i pipeline'y CI nie dryfowały. Do lokalnych eksperymentów dobrze sprawdza się szeroko obsługiwany znacznik, taki jak python:3-slim. W przypadku współdzielonych devcontainerów, CI i środowisk produkcyjnych zastąp ten tag zatwierdzonym obrazem przypiętym do skrótu digest z listy dozwolonych obrazów w Twojej organizacji.

Utwórz minimalny Dockerfile dla aplikacji w Pythonie, która łączy się z 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"]

Twój requirements.txt:

mssql-python>=1.11.0

Kompilowanie i uruchamianie:

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

W środowiskach współdzielonych przekaż zatwierdzone niemodyfikowalne odwołanie do bazowego obrazu za pomocą --build-arg PYTHON_BASE=python:3-slim@sha256:<approved-digest>.

Note

Użyj host.docker.internal programu Docker Desktop (Windows i macOS), aby uzyskać dostęp do SQL Server na maszynie hosta. W systemie Linux użyj zamiast tego.--network host

Alpine Linux

Alpine używa musl zamiast .glibc Zainstaluj wymagane pakiety:

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

Konfiguracja usługi Devcontainer

Użyj ponownie tego samego pliku Docker, z którego buduje się twoja aplikacja. To podejście utrzymuje devcontainer w spójności z obrazem środowiska uruchomieniowego i zapobiega rozrzucaniu przypisań wersji Pythona po wielu plikach.

Utwórz .devcontainer/devcontainer.json dla 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"
            ]
        }
    }
}

Aby uwzględnić SQL Server jako usługę w devcontainer, użyj narzędzia 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 (Redaguj wersję):

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

W przypadku współdzielonych przestrzeni roboczych przypnij obraz usługi SQL Server do zatwierdzonego skrótu zamiast polegać na zmiennym tagu. Załaduj MSSQL_SA_PASSWORD z lokalnego pliku .env lub z magazynu sekretów platformy, zamiast dodawać go do systemu kontroli wersji.

Połącz się z usługą SQL Server według nazwy:

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

Zależności specyficzne dla platformy

Sterownik mssql-python zawiera swoje natywne komponenty. Nie musisz instalować zewnętrznego menedżera sterowników ODBC. Jednak sterownik wymaga niewielkiego zestawu bibliotek systemowych na Linuksie i macOS.

Platforma Wymagane pakiety Zainstaluj polecenie
Windows Żaden Zawarte w kole.
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 (poprzez Homebrew) brew install openssl

Dla macOS, jeśli napotkasz błędy SSL, ustaw flagi linkera:

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

Pełne instrukcje instalacji można znaleźć w artykule Install mssql-python.

Uwierzytelnianie na potrzeby programowania

Lokalne tworzenie aplikacji z użyciem Azure SQL

Zastosowanie ActiveDirectoryDefault do uwierzytelniania bez hasła. Ta opcja automatycznie łączy się z Azure CLI, Visual Studio, zmiennymi środowiskowymi oraz zarządzaną tożsamością:

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

Upewnij się, że jesteś zalogowany za pomocą Azure CLI:

az login

Lokalne programowanie z użyciem SQL Server

Użyj uwierzytelniania SQL z lokalną instancją.

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

Tworzenie aplikacji kontenerowych dla usługi Azure SQL

Dla kontenerów działających w Azure (App Service, Container Apps, AKS) użyj managed identity.

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

W przypadku kontenerów działających lokalnie, które muszą łączyć się z Azure SQL, upewnij się, że kontener ma źródło poświadczenia, które ActiveDirectoryDefault można wykorzystać. Najbardziej wiarygodne opcje to:

  • Zainstaluj Azure CLI w kontenerze i zaloguj się tam. Montuj ~/.azure z hosta tylko wtedy, gdy obraz kontenera już zawiera Azure CLI i zamierzasz ponownie wykorzystać tę pamięć podręczną.
  • Podaj poświadczenia jednostki usługi za pomocą zmiennych środowiskowych, takich jak AZURE_CLIENT_ID, AZURE_TENANT_ID oraz AZURE_CLIENT_SECRET.

Następnie użyj ActiveDirectoryDefault w swoim kodzie połączenia.

Obsługiwane endpointy Microsoft SQL

Sterownik mssql-python łączy się ze wszystkimi endpointami Microsoft SQL:

Endpoint Authentication
SQL Server (lokalnie lub w maszynie wirtualnej) uwierzytelnianie SQL, uwierzytelnianie systemu Windows
Azure SQL Database Microsoft Entra ID (zalecane), uwierzytelnianie SQL
Azure SQL Managed Instance Microsoft Entra ID (zalecane), uwierzytelnianie SQL
Azure Synapse Analytics (dedykowane pule) Microsoft Entra ID, uwierzytelnianie SQL
Baza danych SQL na platformie Fabric Microsoft Entra ID
Hurtownia danych Fabric Microsoft Entra ID
Analityczny punkt końcowy SQL (Lakehouse) Microsoft Entra ID
Punkt końcowy analizy SQL (dublowana baza danych) Microsoft Entra ID

Zobacz Microsoft Entra authentication dla wszystkich siedmiu trybów uwierzytelniania oraz Support Life Cycle dla pełnej matrycy kompatybilności.

Konfiguracja potoku ciągłej integracji

GitHub Actions

Trzymaj runtime Python w jednej zmiennej, żeby móc go przeglądać i aktualizować w jednym miejscu. Użyj 3.x w szybko zmieniających się potokach walidacji albo zastąp go zatwierdzoną przez organizację konkretną wersją w potokach wydaniowych.

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

W przypadku współdzielonych potoków zastąp hasło zastępcze w linii zaszyfrowanym sekretem, przypiń obraz usługi SQL Server do digestu i zachowaj wersję Python w zmiennej zarządzanej organizacją lub w wielorazowym wejściu workflow.

Azure Pipelines

Użyj zasobu kontenerowego, aby uruchomić SQL Server jako usługę równolegle z zadaniem testowym:

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

Podobnie jak w GitHub Actions, zastąp hasło zastępcze osadzone bezpośrednio w kodzie zmienną secret, zanim użyjesz tego rozwiązania poza tymczasowym potokiem demonstracyjnym.

Zabezpieczenia i sekrety

Nie wpisuj na stałe haseł do baz danych ani ciągów połączenia w kodzie źródłowym ani plikach Dockerfile. Zamiast tego używaj zmiennych środowiskowych i zarządzania sekretami.

Zmienne środowiskowe dla rozwoju lokalnego

Przechowuj dane uwierzytelniające w zmiennych środowiskowych lub plikach .env wykluczonych z kontroli źródeł:

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

Dla Docker Compose, odwołaj się do pliku .env :

services:
  app:
    build: .
    env_file: .env

Caution

Nigdy nie zatwierdzaj plików .env w systemie kontroli wersji. Dodaj .env do .gitignore pliku.

Sekrety CI/CD

W potokach CI używaj sekretnego magazynu platformy zamiast zmiennych środowiskowych w tekście jawnym:

Higiena łańcucha dostaw kontenerów

Stosuj te praktyki w współdzielonych środowiskach deweloperskich i CI:

  • Trzymaj referencje do obrazów w jednym miejscu, na przykład w Dockerze ARG, buildzie devcontainera czy zmiennej pipeline.
  • Przypnij współdzielone obrazy kontenerów do niezmiennych skrótów zamiast do pływających tagów.
  • Przeglądaj i odświeżaj przypięte skróty poprzez zatwierdzony proces aktualizacji, taki jak Dependabot, Renovate lub wewnętrzny proces promocji obrazów.
  • Zatwierdz plik blokady zależności, taki jak uv.lock, lub użyj zhaszowanych plików wymagań do odtwarzalnych instalacji Python.
  • Preferuj zatwierdzone przez organizację obrazy bazowe oraz lokalne mirrory rejestrów, jeśli platforma je udostępnia.

Produkcja: uwierzytelnianie bez hasła

Dla obciążeń produkcyjnych na Azure SQL używaj uwierzytelniania Microsoft Entra z zarządzaną tożsamością. To podejście całkowicie eliminuje hasła:

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

W aplikacjach, które muszą przechowywać sekrety, takie jak hasła do uwierzytelniania SQL, użyj Azure Key Vault i pobieraj je w czasie działania.

Zarządzanie zależnościami za pomocą UV

UV to szybki instalator pakietów Python, który dobrze działa w CI i kontenerach:

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

W CI:

pip install uv
uv sync
uv run pytest

Rozwiązywanie typowych problemów z kontenerem

Objaw Przyczyna Napraw.
ImportError: libltdl.so.7 Brakuje biblioteki systemowej. Zainstaluj libltdl7 (Debian) lub libltdl (Alpine).
ImportError: libkrb5.so.3 Zaginiona biblioteka Kerberosa. Zainstaluj libkrb5-3 (Debian) lub krb5-libs (Alpine/RHEL).
SSL: CERTIFICATE_VERIFY_FAILED Certyfikat z podpisem własnym na lokalnym serwerze SQL Server. Dodaj trust_server_certificate="yes" do połączenia. Nie używaj tego w produkcji.
Odmowa połączenia na porcie 1433 SQL Server kontener nie jest gotowy. Dodaj kontrolę kondycji lub poczekaj na uruchomienie usługi.
Login failed for user 'sa' Hasło nie spełnia wymagań dotyczących złożoności. Używaj hasła z wielkimi, małymi literami, cyframi i znakami specjalnymi.
Cannot open database Baza danych jeszcze nie istnieje. Utworzenie lub przywrócenie bazy danych przed połączeniem.
Powolne nawiązywanie pierwszego połączenia w kontenerze Uruchamianie rozpoznawania nazw DNS lub łańcucha poświadczeń. Dla lokalnego SQL Server użyj localhost,1433 zamiast nazwy hosta. W przypadku usługi Azure SQL uwierzytelnij się wcześniej za pomocą az login.