使用 mssql-python 進行容器與本地開發

本指南涵蓋了針對 Python 開發者在 Windows、Linux、macOS、Docker 容器、開發容器及 CI 管線中操作驅動mssql-python程式的環境設定。

先決條件

  • Python 3.10 或更新版本。
  • Docker Desktop(用於容器式開發)。
  • 一個相容 x64 的主機(Intel、AMD 或 x64 虛擬機),用於 SQL Server Linux 容器。 SQL Server Linux 容器不支援 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> 替換為您環境中的值。

使用 sqlcmd 在建立時輸出的連線詳細資料,從 Python 進行連線。 使用 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> 以建立一個容器,裡面有一個空的使用者資料庫,準備開發。

VS Code 的本地 SQL Server

VS Code 的 SQL Server 擴充功能(ms-mssql.mssql)可直接從編輯器建立本地 SQL Server 容器:

  1. 在活動欄開啟 SQL Server 檢視。
  2. 選擇新增連線>建立本地 SQL Server(或使用指令面板:MS SQL: Create Local 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前一節的做法會自動處理下載與還原。

適用於 Python 應用程式的 Dockerfile

把 Python 基礎映像參考放在一處,這樣本地建置、開發容器和 CI 管線就不會漂移。 對於局部實驗,像是廣泛支援的標籤 python:3-slim 效果很好。 對於共享開發容器、CI 和生產環境,請用組織允許清單中核准的摘要置頂映像檔替換該標籤。

為連接 Microsoft SQL 的 Python 應用程式建立一個簡約的 Docker 檔案:

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> 傳遞經核准的不可變基底映像參考。

Note

在 Docker 桌面(Windows 和 macOS)上使用host.docker.internal,以存取主機上的 SQL Server。 在 Linux 上,請改用--network host

阿爾卑斯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"]

開發容器設定

沿用應用程式建置時使用的同一個 Dockerfile。 這種方法能讓開發容器與你的執行時映像對齊,並防止 Python 版本的腳位分散在多個檔案中。

為 VS Code 建立 .devcontainer/devcontainer.json

{
    "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 作為服務納入開發容器,請使用 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 作業系統 None 已包含在滾輪中。
Ubuntu / Debian libltdl7libkrb5-3libgssapi-krb5-2 sudo apt-get install libltdl7 libkrb5-3 libgssapi-krb5-2
Red Hat / CentOS / Fedora libtool-ltdlkrb5-libs sudo dnf install libtool-ltdl krb5-libs
Alpine libltdlkrb5-libs apk add libltdl krb5-libs
macOS OpenSSL(透過 Homebrew) brew install openssl

在 macOS 中,如果遇到 SSL 錯誤,請設定連結器旗標:

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

完整安裝說明請參閱 Install 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),使用 managed identity。

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

對於本地執行且需要連接 Azure SQL 的容器,請確保容器有可用的憑證來源ActiveDirectoryDefault。 最可靠的選項有:

  • 在容器中安裝 Azure CLI 並登入。 只有當容器映像已經包含 Azure CLI 且你打算重複使用該憑證快取時,才從主機掛載~/.azure
  • 透過環境變數 AZURE_CLIENT_ID如 、 AZURE_TENANT_IDAZURE_CLIENT_SECRET提供服務主體憑證。

然後在你的連線碼裡使用 ActiveDirectoryDefault

支援的 Microsoft SQL 端點

驅動mssql-python程式連接所有 Microsoft SQL 端點:

終點 Authentication
SQL Server(本地或虛擬機中) SQL 認證,Windows 認證
Azure SQL Database Microsoft Entra ID (建議)、SQL 驗證
Azure SQL 受控執行個體 Microsoft Entra ID(建議使用), SQL 驗證
Azure Synapse Analytics(專用集區) Microsoft Entra ID, SQL auth
Fabric 中的 SQL 資料庫 Microsoft Entra ID
Fabric 資料倉儲 Microsoft Entra ID
SQL 分析端點(Lakehouse) Microsoft Entra ID
SQL 分析端點(鏡像資料庫) Microsoft Entra ID

完整相容矩陣請參閱 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 一樣,在將此模式用於一次性示範管線以外的情況之前,請先將內嵌的佔位符密碼替換為祕密變數。

安全與祕密

不要在原始碼或 Dockerfile 裡硬編碼資料庫密碼或連線字串。 改用環境變數和秘密管理。

地方開發的環境變數

將憑證儲存在環境變數中,或儲存在已排除於版本控制之外的 .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

Caution

切勿將 .env 檔案提交到原始碼控制。 把它加 .env 到你的 .gitignore 檔案裡。

CI/CD 機密

在 CI 管線中,使用平台的秘密儲存庫,而非純文字環境變數:

  • GitHub Actions:使用加密密碼,並以 ${{ secrets.SQL_PWD }} 參照它們。
  • Azure Pipelines:使用祕密變數,並將其參考為 $(SQL_PWD)

貨櫃供應鏈衛生

請在共享開發環境與整合環境中使用以下做法:

  • 將映像參照集中在同一處,例如 Docker ARG、開發容器建置或管線變數。
  • 將共用容器映像固定為不可變摘要,而非可變標籤。
  • 透過核准的更新流程(如 Dependabot、Renovate 或內部圖片推廣流程)審查並刷新置頂摘要。
  • 提交相依性鎖定檔(例如 uv.lock),或使用含雜湊值的 requirements 檔案,以確保 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 進行預先驗證。