mssql-python 載入兩個原生 ODBC 提供者之一:
| Provider | 是什麼 | Status |
|---|---|---|
msodbcsql18 |
Microsoft ODBC Driver 18 for SQL Server,成熟的 C++ 驅動程式 | 預設,未變更 |
mssql-odbc |
一個用 Rust 撰寫的新 ODBC 驅動程式 | 預覽,加入 |
本文將介紹 mssql-odbc0.3.0、mssql-python 目前使用的版本,以及與 msodbcsql18 的差異。
Note
mssql-odbc 目前正積極開發與驗證中。 它尚未完全取代 Microsoft ODBC Driver 18。 暫時把 msodbcsql18 它當作你的生產預設。 開發團隊計畫在即將推出的版本中彌補預覽缺口,唯獨本文明確指出的有意排除部分除外。
Availability
驅動程式隨 mssql-python-rs 套件提供,並以適用於 CPython 3.10 及更新版本的預先建置 wheel 套件形式發行:
| Platform | Architectures |
|---|---|
| Windows | x64;CPython 3.11+ 上的 ARM64 |
| macOS | Universal 2(x86_64 + arm64)、macOS 15 或更新版本 |
| Linux (glibc) | x86_64、aarch64 — manylinux_2_28 以及 manylinux_2_34 |
| Linux(musl) | x86_64,aarch64 — musllinux_1_2 |
啟用驅動程式
該 mssql-python 套件依賴於 mssql-python-rs,因此一般安裝會帶來 Rust 驅動程式:
pip install mssql-python
如果你是用 --no-deps 或從私有索引安裝,也要明確安裝 mssql-python-rs 。
在 第一個連線前選擇提供者,使用環境變數:
PowerShell:
$env:MSSQL_PYTHON_NATIVE_PROVIDER = "mssql-odbc"
Bash 或 Zsh:
export MSSQL_PYTHON_NATIVE_PROVIDER=mssql-odbc
或從 Python:
import mssql_python
mssql_python.native_provider = "mssql-odbc"
透過使用你應用程式現有的 連接字串 來連接。 讓憑證驗證保持啟用(Encrypt=yes;TrustServerCertificate=no)。 關於認證與憑證設定,請參見 連線字串 及 加密與憑證。
connection = mssql_python.connect(connection_string)
驅動程式在選擇服務提供者時會依以下規則進行:
-
MSSQL_PYTHON_NATIVE_PROVIDER環境變數優先於native_provider。 衝突的屬性指派會發出RuntimeWarning。 - 選擇在連接字串驗證後且原生連接建構前即固定。 後續連線失敗不會清除該選擇。 較早發生的連線字串剖析錯誤或遺漏提供者套件,都無法解決這個選擇問題。 選定後,將
native_provider變更為其他供應商會產生RuntimeWarning訊號,且不會生效。 重新啟動此程序以切換提供者。 - 未識別的提供者名稱會引發
ValueError;驅動程式不會回退到預設提供者。 被指定為native_provider的未知名稱會立即引發錯誤。 當你嘗試連線時,環境變數中有一個未知的名稱會引發錯誤。 - 將
native_provider設為None,以在屬性選擇變成固定之前清除該選擇。 環境變數仍然優先。
呼叫 mssql_python.get_native_provider_info() 以檢查所選供應商、選擇來源,以及是否已固定。 在連線前,這僅表示所選項目,而不是證明原生驅動程式已成功載入。
要回去,請將變數設為 msodbcsql18,或取消設定並移除程式碼中的任何 native_provider 賦值(或設為 "msodbcsql18")。
然後重新開始這個過程。
目前可行的做法
mssql-odbc驅動程式實作了mssql-python會呼叫的所有 ODBC 函式,因此大多數應用程式可以在不修改程式碼的情況下切換提供者。 請查看 已知問題 以了解剩餘的差異。
| Area | Notes |
|---|---|
| 連線生命週期 | 連線、close()with區塊、登入逾時、診斷,以及更改目前資料庫。 連接字串設定包括 ApplicationIntent、MultiSubnetFailover、IpAddressPreference、PacketSize、KeepAlive,以及 ConnectRetryCount / ConnectRetryInterval(閒置連線恢復能力)。 |
| Authentication | SQL 認證(UID / PWD);Windows 驗證(Trusted_Connection=Yes,在 Windows 上使用 SSPI,於 Linux 與 macOS 上使用 Kerberos);以及 Microsoft Entra 互動式、裝置程式碼、服務主體、受控識別、預設認證與存取權杖。 不支援 Entra 整合與密碼驗證;詳見已知問題。 |
| TLS |
Encrypt、TrustServerCertificate、HostnameInCertificate 和 ServerCertificate。 |
| 查詢執行 | 直接與預備執行、預備計畫重用、qmark 參數,以及 pyformat 所執行的轉換 mssql-python。 |
| ODBC 轉義語法 | 函數、日期/時間、外部聯結、GUID、LIKE ... {escape ...}、間隔和 {encrypt ...} 逸出形式。 |
| 預存程序 | 用 T-SQL 或透過 execute() 的位置 {call ...} 語法呼叫它們,讀取結果集,然後使用 nextset() 前進。 |
| 輸入參數 | 標量參數、SQL NULL、 setinputsizes()以及混合的常規/串流參數。 |
| 大型參數 | 大文字與二進位參數會依一般綁定路徑串流至伺服器;XML 與 UDT 參數的限制如下。 |
executemany() |
使用 ODBC 參數陣列批次處理。 包含串流值的列會回退到逐列執行。 |
| 取得資料列 |
fetchone()、fetchmany()、fetchall()、迭代、fetchval()、類型轉換,以及大型文字/二進位串流。 |
| 擷取箭頭 |
arrow_batch()
arrow()和 arrow_reader()。 需要 pyarrow。 |
| 多個結果集 |
nextset(),包括由參數陣列產生的結果。 |
| Transactions | 自動提交、提交、回滾、當 with connect(...) 區塊結束時發生的自動提交(或若錯誤未被攔截則回滾),以及讀取未提交、讀取已提交、可重複讀取、可序列化和快照隔離層級。 |
| 查詢逾時 | 將 Connection.timeout 設為秒數,以限制該連線游標執行的陳述式;逾時時會引發 OperationalError。
0 代表沒有逾時。 這個設定與以 connect(timeout=...) 傳遞的登入逾時設定是分開的。 |
| 連線池化 | 內建的mssql-python集區,包括取用時重設連線,以及依 Microsoft Entra 身分分開的集區。 |
| 中繼資料 API |
tables()、columns()、、primaryKeys()、foreignKeys()statistics()rowIdColumns()rowVerColumns()procedures()和。getTypeInfo() |
| 編碼與轉換器 | 預設寬字元編碼與輸出轉換器。 自訂窄字元解碼及非 Unicode 參數轉換有限制,詳見 已知問題。 |
數據類型
你可以讀取所有 SQL Server 的資料型別,驅動程式也支援 mssql-python 繫結的每一種參數類型。 驅動程式將 xml、json 和 vector 的值作為 vector 回傳(str 作為 JSON 陣列),並將 geometry、geography 和 hierarchyid 等 CLR 類型作為 bytes 回傳。 關於其他 Python 映射,請參見資料型別映射。
關於類型特定的限制,請參見 已知問題。
已知問題
在從 msodbcsql18 切換工作負載之前,先檢查這些差異。
| Issue | Details | Workaround |
|---|---|---|
| Microsoft Entra 整合式驗證 | 不支援 Authentication=ActiveDirectoryIntegrated。 Windows 驗證(Trusted_Connection=Yes)不受影響。 |
使用其他 Microsoft Entra 方法,或保留 msodbcsql18。 |
| Microsoft Entra 密碼驗證 |
Authentication=ActiveDirectoryPassword 不支援,也沒有計畫支援,因為這種方法無法滿足多重因素驗證(MFA)。 SQL 認證(UID / PWD)則不受影響。 |
使用其他 Microsoft Entra 方法,例如服務主體、管理身份或存取權杖。 |
attrs_before 設定 |
認證、應用程式意圖和多子網故障轉移不能以數字屬性來設定。 除查詢逾時外,其他陳述式屬性都會被拒絕。 | 使用等效的連接字串關鍵字。 |
| 連線操作逾時 |
set_attr(SQL_ATTR_CONNECTION_TIMEOUT, ...) 接受並儲存該值,但在 0.3.0 版本中不會強制執行逾時限制。 |
用於 connect(timeout=...) 登入和 Connection.timeout 陳述式;兩者都不是一般連線作業逾時期限。 |
| 多位址主機 |
msodbcsql18 預設啟用透明網路 IP 解析(TNIR); mssql-odbc 但不支援 TNIR。
mssql-python 拒絕任一提供者的 TransparentNetworkIPResolution 連接字串關鍵字。 未使用 MultiSubnetFailover=Yes 時,則會一次嘗試一個位址,因此無法連線的位址可能會延遲連線。 伺服器輔助的 DNS 快取和增強路由未進行協商。 |
將 MultiSubnetFailover=Yes 設定給可用性群組接聽程式及其他多位址主機。 |
| 暫時性的 DNS 故障 | 如果 DNS 查詢失敗,驅動程式不會回退到最後成功地址。 (#457) | 重試連線。 |
| 資料分類 | 敏感度分類中繼資料無法取得,且 SQL_COPT_SS_DATACLASSIFICATION_VERSION(1400)不受支援。 |
查詢 sys.sensitivity_classifications。 |
| 多執行緒 | 多執行緒使用尚未被驗證。 | 將 msodbcsql18 保留給多執行緒工作負載。 |
fork() 連線後 |
在 Linux 上,父程序連接後 fork 出的程序在使用驅動程式時可能會當機,即使有新的連線。 啟用池化後,父節點也可能會無回應。 (#566) | 使用 spawn 起始法,並在每個工作程序內連線。 |
| 取消正在執行的陳述式 | 正在進行的查詢或取回無法被中斷。 例如,關閉 arrow_reader() 並不會停止另一個執行緒上正在進行的讀取作業。 |
用 Connection.timeout 來限制長時間執行的陳述式。 |
| 未讀的結果 | 關閉游標或執行其他語句會讀取並丟棄剩餘結果,而非取消,這可能會很慢。 關閉使用已準備好語句的游標會忽略 Connection.timeout,且如果伺服器停止回應,可能會當機。 (#546) |
只取你需要的資料列,例如使用 TOP。 |
大型物件 xml 與 UDT 參數 |
綁定為 SQL_SS_XML 或 SQL_SS_UDT 到 setinputsizes() 的值會緩衝在記憶體中,而非串流。 |
將 xml 值繫結為普通字串。 |
空 image 值 |
空且非 NULL 的 SQL Server image 值會回傳為 None 而非 b""。 |
閱讀 CAST(image_column AS varbinary(max)),或在空/NULL 區分重要時使用 msodbcsql18 。 |
| 非 Unicode 字串參數 | 綁定為 char / varchar 到 setinputsizes() 的字串在代碼頁 437、代碼頁 850 及 UTF-8 排序中可能被錯誤編碼。 |
使用預設的字串綁定。 |
| Windows 上的舊有程式碼頁解碼 | 使用 setdecoding(SQL_CHAR, encoding="cp1252") 或其他舊有代碼頁時,文字可能被錯誤解碼或回傳為 bytes,因為驅動程式回傳 char / varchar 資料為 UTF-8。 |
使用預設值: conn.setdecoding(mssql_python.SQL_CHAR)。 |
Connection.getinfo() |
SQL_USER_NAME 回傳 connection-string UID,而非資料庫使用者。 當沒有 UID 到達駕駛時,車廂是空的。 某些能力值與基於封包大小的限制不同於 msodbcsql18。 |
資料庫使用者請使用 SELECT USER_NAME()。 |
| 記憶體不足失敗 | 部分驅動程式配置失敗會終止 Python 程序,而非引發 MemoryError。 (#484) |
限制你傳送和取回的值大小。 |
| 大值讀取效能 | 在一項基準測試中,資料的分塊讀取varchar(max) / nvarchar(max)比使用msodbcsql18時略慢。 (#473) |
為您的工作負載進行基準測試。 |
此列表並不詳盡。
回報問題
如果遇到錯誤,選擇 msodbcsql18、 重新啟動程序,並檢查該行為是否仍然發生。 同時移除任何在 Python 端衝突的提供者設定。 這種比較有助於定位問題;它本身並不能證明其成因。 包含 mssql_python.get_native_provider_info() 的輸出、你的平台,以及失敗的 SQL 或錯誤訊息:
- Rust 驅動程式問題: https://github.com/microsoft/mssql-rs/issues
-
mssql-python問題: https://github.com/microsoft/mssql-python/issues
對於 Rust 驅動程式的診斷,請在啟動 Python 前設定這些變數,並選取 mssql-odbc 後重現問題。 例如:在 PowerShell 中:
$env:MSSQL_TDS_TRACE = "true"
$env:MSSQL_TDS_TRACE_LEVEL = "warn,mssqlodbc=debug"
$env:MSSQL_TDS_TRACE_DIR = "./traces"
MSSQL_TDS_TRACE 啟用追蹤、MSSQL_TDS_TRACE_LEVEL 選擇日誌過濾器,並由 MSSQL_TDS_TRACE_DIR 將輸出寫入各程序的檔案,而非 stderr。
更改這些設定後重新啟動 Python。 追蹤可以包含 SQL 文字和參數值。 在分享相關摘錄前,請審查並遮蔽敏感資料,診斷後則關閉追蹤功能。