診斷並解決 SQL Server、Azure SQL Database、Azure SQL 受控執行個體 及 Microsoft Fabric 中 SQL 資料庫後端常見問題mssql-django。
連接問題
本節將介紹最常見的連線錯誤及其解決方法。
找不到 ODBC 驅動程式
徵兆:
django.core.exceptions.ImproperlyConfigured: 'ODBC Driver 18 for SQL Server' is not a recognized ODBC driver
Or:
Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 18 for SQL Server'")
多個原因與解決方案:
未安裝 ODBC 驅動程式
安裝 Microsoft 的 SQL Server ODBC 驅動程式。 欲下載連結,請參閱下載 SQL Server 的 ODBC 驅動程式。
安裝多個驅動程式版本
請在 :
settings.py中指定精確的驅動程式名稱或路徑:DATABASES = { "default": { "ENGINE": "mssql", "NAME": "<your-database>", "USER": "<your-username>", "PASSWORD": "<your-password>", "HOST": "<your-server>", "PORT": "1433", "OPTIONS": { "driver": "ODBC Driver 17 for SQL Server", }, }, }在 Linux 上,請指定完整路徑:
"OPTIONS": { "driver": "/opt/microsoft/msodbcsql17/lib64/libmsodbcsql-17.10.so.6.1", },檢查已安裝的驅動程式
- 在 Linux/macOS 上,執行
odbcinst -q -d。 - 在 Windows 上,請在管理工具中檢查 ODBC 資料來源。
- 在 Linux/macOS 上,執行
連線被拒
徵兆:
django.db.utils.OperationalError: ('08001', '[08001] ... TCP Provider: Error code 0x2749 ...')
多個原因與解決方案:
SQL Server 上未啟用 TCP/IP
- 開啟 SQL Server 組態管理員。
- 在 SQL Server 網路設定中啟用 TCP/IP。
- 在 TCP/IP 屬性中,啟用用於該連線的 IP 位址。
- 重新啟動 SQL Server 服務。
防火牆阻擋埠 1433
- 確認防火牆規則是否允許在 1433 埠接入連線。
- 對於 Azure SQL,請在 Azure portal 防火牆設定中新增你的客戶端 IP。
伺服器名稱或埠口錯誤
確認您設定中的
HOST和PORT值。
登入失敗
徵兆:
django.db.utils.OperationalError: ('28000', "[28000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<username>'.")
多個原因與解決方案:
錯誤的資格證明
請驗證使用者名稱和密碼。
使用者不存在
確認登入是否映射到目標資料庫中的使用者。
SQL Server 認證已停用
啟用混合模式驗證,或使用 Windows 或 Microsoft Entra 認證。
連線超時
徵兆:
django.db.utils.OperationalError: ('HYT00', '[HYT00] [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired')
多個原因與解決方案:
網路等待時間
在 OPTIONS 中增加
connection_timeout。伺服器過載
增加
connection_retries且connection_retry_backoff_time。"OPTIONS": { "driver": "ODBC Driver 18 for SQL Server", "connection_timeout": 30, "connection_retries": 5, "connection_retry_backoff_time": 10, },
移轉問題
這些錯誤發生在 Django 對 SQL Server 的遷移操作中。
日期與時間問題
Now() 值會在 USE_TZ=True 時位移
徵兆:
使用 Django Now()、auto_now 或 auto_now_add 寫入的時間戳記,在 SQL Server 主機時區不是 UTC 時會發生位移。
解決方案:升級到 mssql-django 1.7.2 或更新版本。 版本 1.7.2 修正了具時區感知能力的 Now() SQL 產生,以及 datetimeoffset 偏移處理。
AttributeError 呼叫 .explain() 時
徵兆:
AttributeError: ... explain_format ...
解決方案:升級到 mssql-django 1.7.2 或更新版本。 1.7.2 版本修正了 Django 4.0 及以後版本的編譯器相容性,說明了元資料。
無法更改 AutoField
徵兆:
django.db.utils.ProgrammingError: Cannot alter column to or from an IDENTITY column
解決方案:SQL Server 不支援將欄位從或變更為 AutoField。 建立一個想要的欄位類型的新模型,手動遷移資料,然後丟棄舊資料表。 有關解決方法,請參見 mssql-django 的資料庫遷移。
重命名在外鍵限制下失敗
徵兆:
django.db.utils.ProgrammingError: ... could not drop constraint ...
解決方案:SQL Server 需要在重新命名欄位前先捨棄外鍵約束。 在您的遷移過程中使用 SeparateDatabaseAndState。 舉例來說,請參考 mssql-django 的資料庫遷移。
編碼問題
編碼錯誤通常發生在pyodbc誤解 SQL Server 的字元資料時。
Unicode 編碼錯誤
徵兆:
UnicodeDecodeError: 'utf-8' codec can't decode byte ...
解決方案:在 OPTIONS 字典中設定 pyodbc 編碼:
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"unicode_results": True,
},
FreeTDS 問題
FreeTDS 需要與 Microsoft ODBC 驅動程式不同的特定設定。
host_is_server 錯誤
徵兆:
使用未指定 host_is_server的 FreeTDS 時連線失敗。
解決方案:設定 host_is_server 為 True 使用 FreeTDS 時:
"OPTIONS": {
"driver": "FreeTDS",
"host_is_server": True,
},
欲了解更多 FreeTDS 設定資訊,請參閱 mssql-django 的連線選項。
測試資料庫問題
測試資料庫的建立與銷毀可能會因你的認證方式而失敗。
無法建立使用管理身份的測試資料庫
徵兆:
django.db.utils.DatabaseError: ('42000', '[42000] ... EXECUTE permission denied on object ...')
Or:
django.db.utils.OperationalError: ('28000', ... login failed ...)
當你使用 ActiveDirectoryMsi (管理身份)驗證時,測試執行者無法建立或銷毀測試資料庫。 此限制存在的原因在於:
管理身份憑證是從主機環境(例如 Azure VM 和 App Service)取得的。
測試執行器在 teardown 期間會嘗試使用 test 資料庫憑證進行連線。
管理身份可以被賦予資料庫層級的角色,但測試資料庫的建立與刪除通常需要伺服器層級的權限,而測試執行者往往沒有這些權限。
受影響的認證方式:
-
ActiveDirectoryMsi(Azure managed identity) -
ActiveDirectoryServicePrincipal(僅在伺服器範圍內設定時)
支援的認證方法 (測試資料庫建立可行):
ActiveDirectoryPasswordActiveDirectoryIntegrated- SQL 認證(使用者名稱/密碼)
測試環境中的身分驗證取捨
| 方法 | 無秘密 | 可配合自動建立/刪除測試資料庫運作 | 典型用途 |
|---|---|---|---|
ActiveDirectoryMsi |
Yes | 通常不會(除非有伺服器層級的權限) | Azure 託管的生產工作負載 |
ActiveDirectoryServicePrincipal |
否(用戶端密碼/憑證) | 這取決於被授予的伺服器層級權限 | 採用明確身分管理的 CI/CD |
ActiveDirectoryPassword |
否 | 是的(只要有足夠的 SQL 權限) | 開發人員與受控的 CI 環境 |
| SQL 驗證 | 否 | 是的(只要有足夠的 SQL 權限) | 局部或隔離測試環境 |
解決方案:
開發時:使用
--keepdb旗標以略過測試資料庫的清理:python manage.py test --keepdb針對 CI/CD 管線:預先建立專用測試資料庫並授予受管理身份
CREATE TABLE與ALTER權限:-- Connect as a server admin, then: USE [test_database_name]; -- Grant permissions for managed identity (replace with your identity name) CREATE USER [your-app-identity] FROM EXTERNAL PROVIDER; GRANT CREATE TABLE TO [your-app-identity]; GRANT ALTER ON SCHEMA::dbo TO [your-app-identity];替代方案:測試環境使用 SQL 認證,或在 CI/CD 測試執行器中切換至
ActiveDirectoryPasswordSQL 認證。
回退程序
當遷移中途失敗時,請使用此回滾序列回到已知良好狀態:
停止應用程式寫入以避免額外的結構漂移。
檢視移轉狀態:
python manage.py showmigrations python manage.py sqlmigrate <app_label> <migration_number>回復到上一個已知正常的遷移版本:
python manage.py migrate <app_label> <previous_migration>如果結構描述與遷移歷史不一致,只有在確認實際資料庫架構後,才可使用
--fake謹慎修復狀態。先在暫存環境中重執行遷移,然後再嘗試生產環境。
Important
對於破壞性遷移,如丟棄、重命名及欄位型別變更,部署前請先進行測試備份。 如果無法透過遷移回滾,請從備份還原並重新套用已驗證的遷移。
Docker 與容器問題
容器映像需要明確安裝 ODBC 驅動程式及建置相依關係。
貨櫃中找不到 ODBC 驅動程式
徵兆:
Error: ('01000', "[01000] [unixODBC][Driver Manager]Can't open lib 'ODBC Driver 18 for SQL Server'")
多個原因與解決方案:
ODBC 驅動程式未安裝在容器映像中
Slim 或 Alpine 的基礎映像檔不包含 ODBC 驅動程式。 新增 Microsoft APT 儲存庫,並在你的 Dockerfile 中安裝
msodbcsql18。 完整 Dockerfile 範例請參見 Deploy to App Service 。遺失包裹
unixodbc-devpyodbcwheel 連結至libodbc.so。 安裝 Python 套件前,先安裝unixodbc-dev(Debian/Ubuntu)或unixODBC-devel(RHEL/Fedora)。
PYODBC 未能在薄型映像上建構
徵兆:
error: command 'gcc' failed: No such file or directory
Or:
fatal error: sql.h: No such file or directory
解決方案:先安裝建置相依性,再進行 pip install:
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
g++ \
unixodbc-dev
或者,使用多階段製作來保持最終影像的體積小:
# Build stage
FROM python:3.12-slim AS builder
RUN apt-get update && apt-get install -y --no-install-recommends gcc g++ unixodbc-dev
COPY requirements.txt .
RUN pip wheel --no-cache-dir --wheel-dir /wheels -r requirements.txt
# Runtime stage
FROM python:3.12-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
curl gnupg2 unixodbc \
&& curl -fsSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o /usr/share/keyrings/microsoft-prod.gpg \
&& curl -fsSL https://packages.microsoft.com/config/debian/12/prod.list > /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 \
&& apt-get purge -y --auto-remove curl gnupg2 \
&& rm -rf /var/lib/apt/lists/*
COPY --from=builder /wheels /wheels
RUN pip install --no-cache-dir /wheels/*
容器無法連接到 SQL Server
徵兆:
django.db.utils.OperationalError: ('08001', '... TCP Provider: Error code 0x2749 ...')
多個原因與解決方案:
Docker Compose 服務名稱未被用作主機
使用 Docker Compose 時,請設
DB_HOST為服務名稱(例如),db而非localhost127.0.0.1。SQL Server 容器尚未準備好
SQL Server 容器啟動需要幾秒鐘。 新增健康檢查或延遲啟動:
services: db: image: mcr.microsoft.com/mssql/server:2022-latest healthcheck: test: /opt/mssql-tools18/bin/sqlcmd -S localhost -U sa -P "$$MSSQL_SA_PASSWORD" -No -Q "SELECT 1" || exit 1 # $$ escapes the $ sign in Docker Compose YAML interval: 10s retries: 10 start_period: 10s web: depends_on: db: condition: service_healthy港口映射衝突
如果主機上有其他 SQL Server 實例,請更改暴露的埠口(例如
1434:1433),並相應更新你的 Django 設定。
Azure SQL 暫時性錯誤復原
後端會mssql-django自動偵測 Azure SQL Database 與 Azure SQL 受控執行個體 連線,方法是查詢 SERVERPROPERTY('EngineEdition')。 在執行 Azure SQL 時,後端會因暫時錯誤(如暫時資源限制或短暫網路中斷)而重試連線。
你可以透過以下connection_retriesconnection_retry_backoff_time選項來調整這個行為:
"OPTIONS": {
"driver": "ODBC Driver 18 for SQL Server",
"connection_retries": 5,
"connection_retry_backoff_time": 5,
},
這些設定僅適用於初始連線建立。 後端不會重試失敗的查詢。 如果連線建立後查詢因暫態錯誤失敗,該例外會傳播到你的應用程式程式碼。 使用應用程式層級的重試邏輯(例如 django-retry-db 或自訂中介軟體)來提升查詢層級的韌性。
慢速查詢與計畫迴歸
這些問題通常需要伺服器端分析以及 Django 層級的查詢審查。
查詢變慢或開始超時
徵兆:
同一個查詢集會隨著時間變慢,或在部署、索引變更或統計資料更新後開始發生逾時。
多個原因與解決方案:
從內建的效能報告開始
對於 SQL Server 和 Azure SQL 受控執行個體,請在 SQL Server Management Studio 中開啟效能儀表板。 對於 Azure SQL Database,請開啟 Query Performance Insight for Azure SQL Database。 這些工具通常比臨時撰寫的 DMV 查詢更適合作為第一步,因為它們能迅速找出高成本查詢、等待情形及資源壓力。
計畫迴歸
使用 查詢存放區 找出慢速查詢,並檢查是否有多個方案。 從 使用 查詢存放區 監視工作負載的最佳做法 中所述的 回歸查詢 和 最耗用資源的查詢 檢視開始。
執行計畫效率低下
開啟該語句的 實際執行計畫 ,檢查是否有資料表或索引掃描、大金鑰查詢、雜湊溢出或不準確的列估計。 背景請參見 執行計畫概述。
錯誤的瓶頸被識別
如果查詢不受 CPU 限制,請使用 查詢存放區 等待統計和 識別瓶頸,以區分 CPU、記憶體、磁碟 I/O、阻塞和連線壓力。
修正被套用在錯誤的層
施行最小有效的修正:新增或調整索引、更新統計、減少選取的欄位和列,或批次處理大型寫入。 如果您需要緊急因應措施,DBA 可以在您修正根本原因的同時,暫時在 查詢存放區 中強制使用已知有效的執行計畫。
使用 dbshell 進行互動式查詢
Django 的 dbshell 管理指令會開啟一個連接到你的資料庫的互動式 SQL shell:
python manage.py dbshell
當您設定 Microsoft ODBC 驅動程式時,後端會使用 sqlcmd;當您使用 FreeTDS 時,則會使用 isql。 確認該工具是否在您的 PATH 上:
-
Windows:
sqlcmd包含在 SQL Server 工具中,或者你可以另外下載。 -
Linux 和 macOS:從 Microsoft 倉庫安裝
mssql-tools18。