mssql-python 2つのネイティブODBCプロバイダーのいずれかを読み込みます:
| Provider | それは何か | Status |
|---|---|---|
msodbcsql18 |
Microsoft ODBC Driver 18 for SQL Server、確立されたC++ドライバ | デフォルト(変更なし) |
mssql-odbc |
Rustで書かれた新しいODBCドライバー | プレビュー オプトイン |
この記事では、mssql-pythonmssql-odbc(が現在使用しているバージョン)と、msodbcsql18との違いについて説明します。
Note
mssql-odbc 現在は積極的な開発と検証中です。 まだMicrosoft ODBC Driver 18の完全な代替ではありません。 今のところ msodbcsql18 を本番のデフォルトとして保っておきましょう。 開発チームは、この記事で明確に指摘された意図的な除外を除き、今後のリリースでプレビューにおける機能差分を解消する計画です。
Availability
ドライバーはCPython 3.10以降のプリビルドホイールとして mssql-python-rs パッケージ内に含まれています。
| Platform | Architectures |
|---|---|
| Windows | CPython 3.11+ 上の x64; ARM64 |
| macOS | universal2 (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 | 注記 |
|---|---|
| 接続ライフサイクル | 接続、 close()、with ブロック、ログインタイムアウト、診断、現在のデータベースの変更などが可能です。 接続文字列の設定には、 ApplicationIntent、 MultiSubnetFailover、 IpAddressPreference、 PacketSize、 KeepAlive、 ConnectRetryCount / ConnectRetryInterval (アイドル接続の回復力)が含まれます。 |
| Authentication | SQL認証(UID / PWD)、Windows 認証(Trusted_Connection=Yes、Windows では SSPI、Linux および macOS では Kerberos を使用)、および Microsoft Entra の対話型、デバイス コード、サービス プリンシパル、マネージド ID、既定の資格情報、アクセス トークン。 Entra統合およびパスワード認証はサポートされていません。「既知の問題」を参照してください。 |
| TLS |
Encrypt、TrustServerCertificate、HostnameInCertificate、ServerCertificate。 |
| クエリの実行 | 直接実行と準備済み実行、事前計画の再利用、qmarkパラメータ、そしてpyformatが実行するmssql-python変換。 |
| ODBCエスケープ構文 | 関数、日付/時間、外部結合、GUID、 LIKE ... {escape ...}、間隔、 {encrypt ...} エスケープフォーム。 |
| ストアド プロシージャ | T-SQLやポジション {call ...} 構文で execute()を通じてそれらを呼び出し、結果セットを読み、nextset()で進めます。 |
| 入力パラメーター | スカラーパラメータ、SQL NULL、 setinputsizes()、そして通常/ストリーム混在パラメーター。 |
| 大きいパラメーター | 大きなテキストおよびバイナリパラメータは通常のバインディングパス上でサーバーにストリーム送信されます。XMLおよびUDTパラメータの制限は以下に記載されています。 |
executemany() |
ODBCパラメータ配列によるバッチ処理 ストリーム値を含む行は行単位実行にフォールバックします。 |
| 行の取得 |
fetchone()、 fetchmany()、 fetchall()、イテレーション、 fetchval()、タイプ変換、そして大規模なテキスト/バイナリストリーミングなどです。 |
| 矢印の取得 |
arrow_batch()、 arrow()、および arrow_reader()。
pyarrow が必要です。 |
| 複数の結果セット |
nextset()パラメータ配列によって生成される結果も含まれます。 |
| Transactions | オートコミット、コミット、ロールバック、with connect(...) ブロック終了時に発生する自動コミット(エラーが発生した場合はロールバック)、そしてread-uncommitted、read-committed、repeatable-read、serializable、snapshot isolationの各レベルです。 |
| クエリのタイムアウト |
Connection.timeout(秒単位)を、その接続のカーソルで実行されるステートメントを制限するように設定します。期限切れになるとOperationalErrorが発生します。
0 はタイムアウトなしを意味します。 この設定は connect(timeout=...)として渡されたログインタイムアウトとは別です。 |
| コネクションプーリング | チェックアウト時の接続リセットや Microsoft Entra アイデンティティごとの個別のプールを含む組み込みのmssql-pythonプール |
| メタデータ API |
tables()、 columns()、 primaryKeys()、 foreignKeys()、 statistics()、 rowIdColumns()、 rowVerColumns()、 procedures()、および getTypeInfo()。 |
| エンコードとコンバーター | デフォルトのワイド文字エンコーディングおよび出力変換器。 カスタムの狭文字デコードや非Unicodeパラメータ変換の制限事項は、既知の問題に記載されています。 |
データの種類
SQL Server のすべてのデータ型を読み取ることができ、ドライバは mssql-python がバインドするすべてのパラメーター型をサポートしています。 ドライバーは xml、 json、 vector の値を str (vector 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 はこれをサポートしていません。
mssql-python は、どちらのプロバイダーでも TransparentNetworkIPResolution 接続文字列キーワードを拒否します。
MultiSubnetFailover=Yesがなければアドレスは一度に一つずつ試されるため、到達不能なアドレスがあると接続が遅れることがあります。 サーバー支援のDNSキャッシュや強化ルーティングはネゴシエートされていません。 |
可用性グループリスナーやその他のマルチアドレスホストのために MultiSubnetFailover=Yes を設定してください。 |
| 一時的なDNS障害 | DNS検索が失敗した場合、ドライバーは最後に成功したアドレスにフォールバックしません。 (#457) | 接続を再試行します。 |
| データの分類 | センシティブ分類のメタデータは利用できず、 SQL_COPT_SS_DATACLASSIFICATION_VERSION (1400)もサポートされていません。 |
クエリ sys.sensitivity_classifications。 |
| マルチスレッド処理 | マルチスレッド利用はまだ検証されていません。 | マルチスレッドのワークロードには msodbcsql18 を維持してください。 |
fork() 接続後 |
Linuxでは、親プロセスの接続後にフォークされたプロセスは、新しい接続でもドライバーを使うとハングすることがあります。 プーリングを有効にしていると、親もハングする可能性があります。 (#566) |
spawnスタート方式を使い、各ワーカー内部で接続してください。 |
| 実行中のステートメントのキャンセル | 実行中のクエリやフェッチは中断できません。 例えば、arrow_reader() を閉じても、他のスレッドで進行中の読み取りが止まるわけではありません。 |
Connection.timeoutを使って長時間実行されるステートメントを制限しましょう。 |
| 未確認の結果 | カーソルを閉じたり別の文を実行したりすると、キャンセルするのではなく、残りの結果を読み取って破棄するため、時間がかかることがあります。 プリペアドステートメントを使っているカーソルを閉じると Connection.timeout が無視され、サーバーが応答しなくなるとハングすることがあります。 (#546) |
例えば TOPで必要な行だけを取得しましょう。 |
大規模 xml と UDT パラメータ |
SQL_SS_XMLまたはsetinputsizes()からSQL_SS_UDTまでにバインドされた値は、ストリーミングされるのではなくメモリ上でバッファリングされます。 |
xml 値を通常の文字列としてバインドします。 |
空の image 値 |
空でNULLでないSQL Server image値はb""ではなくNoneとして返されます。 |
CAST(image_column AS varbinary(max))を読むか、空/NULLの区別が重要な場合はmsodbcsql18を使います。 |
| 非Unicode文字列パラメータ |
char
/
varcharからsetinputsizes()までバウンドされた文字列は、コードページ437、コードページ850、UTF-8のコレーションで誤ってエンコードされることがあります。 |
デフォルトの文字列バインディングを使いましょう。 |
| Windowsにおけるレガシーコードページのデコード |
setdecoding(SQL_CHAR, encoding="cp1252")や他のレガシーコードページでは、ドライバがchar / varcharデータをUTF-8として返すため、テキストが誤ってデコードされたり、bytesとして返されることがあります。 |
デフォルトとして: conn.setdecoding(mssql_python.SQL_CHAR) を使用します。 |
Connection.getinfo() |
SQL_USER_NAME はデータベースユーザーではなく、接続文字列 UID を返します。
UIDがドライバーに届かないときは空っぽだ。 一部の能力値やパケットサイズに基づく制限は msodbcsql18と異なります。 |
データベースユーザーには SELECT USER_NAME() を使いましょう。 |
| メモリ不足エラー | 一部のドライバー割り当ての失敗は、MemoryErrorを送出する代わりにPythonプロセスを終了させることもあります。 (#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のテキストやパラメータの値が含まれることがあります。 関連する抜粋を共有する前に機密データを確認してマスキングし、診断後は追跡機能を無効にしてください。