使用 mssql-odbc 驅動程式(預覽版)

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 驅動程式的診斷,請在啟動 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 文字和參數值。 在分享相關摘錄前,請審查並遮蔽敏感資料,診斷後則關閉追蹤功能。