mssql-python 1.16.0
This release expands platform coverage with Python 3.15, first ever conda release, introduces a new opt-in mssql-odbc provider, improves row and fetch performance, strengthens native runtime packaging, and addresses connection, encoding, UDT, and bulk-copy reliability.
Release Highlights
Python 3.15 Support (#817)
- What changed: Added Python 3.15 wheels and validation across supported Windows, Linux, and macOS x64 and ARM64 platforms. The PyPI release includes 41 prebuilt wheels for supported Python 3.10 through 3.15 environments.
- Who benefits: Applications adopting Python 3.15.
- Impact: Users can move to Python 3.15 without waiting for driver support.
pip install --upgrade mssql-pythonView mssql-python 1.16.0 on PyPI
First Official Conda Release
Version 1.16.0 marks the first official Conda release of the Microsoft Python Driver for SQL Server.
conda install -c microsoft mssql-pythonThe Conda distribution provides one environment-managed package containing the Python bindings and matching native runtimes. Conda selects the compatible build for supported Windows, Linux, and macOS x64 and ARM64 environments, and manages installation and upgrades without mixing pip-managed companion packages into the environment.
View mssql-python on Anaconda.org
New Opt-In mssql-odbc Provider (#730, #804)
- What changed: Added the Rust-based
mssql-odbcprovider through the version-matchedmssql-python-rsruntime. Enable it before the first connection usingMSSQL_PYTHON_NATIVE_PROVIDER=mssql-odbcormssql_python.native_provider = "mssql-odbc". - Who benefits: Applications evaluating or adopting the Rust-based ODBC provider.
- Impact: Users can opt in without changing existing applications; Microsoft ODBC Driver 18 (
msodbcsql18) remains the default.
Enhancements
Dictionary-Style Row Access (#613)
- What changed: Added a read-only
row._mappingview with dictionary conversion and stable column metadata. - Who benefits: Applications that need mapping semantics for fetched rows.
- Impact: Rows integrate with mapping-based code without manually combining values with
cursor.description(GitHub Issue #606).
Separately Packaged Rust Runtime (#768)
- What changed:
mssql-pythonnow installs its Rust runtime through the version-matchedmssql-python-rspackage instead of embedding those files in the main wheel. - Who benefits: Applications using bulk copy and other Rust-backed functionality.
- Impact: Runtime updates can ship through their own platform wheels while remaining exactly aligned with the Python bindings.
Stable-ABI Rust Runtime Wheels (#804)
- What changed: Adopted
mssql-python-rs0.3.0 and its CPython stable-ABI wheels for Python 3.10 and newer. - Who benefits: Users installing the Rust runtime across supported Python versions and platforms.
- Impact: One wheel per OS and architecture now serves multiple supported Python versions.
Updated ODBC Runtime Package (#798, #807)
- What changed: Updated to
mssql-python-odbc==18.6.2.2, separating Linux wheel contents by libc family while retaining the same ODBC Driver 18.6 binaries. - Who benefits: Linux users on glibc-based distributions or Alpine/musl.
- Impact: Each environment receives only its matching ODBC runtime payload.
Faster Row Construction and Batch Fetching (#558)
- What changed: Moved eligible Row construction into the native fetch path and reduced repeated cursor bookkeeping.
- Who benefits: Applications using
fetchone(),fetchmany(), orfetchall(). - Impact: Fetch workloads spend less time in Python-side Row initialization while preserving converters and diagnostics.
Faster Temporal Fetch Conversion (#795)
- What changed: DATE, TIME, and TIMESTAMP values now use checked CPython constructors.
- Who benefits: Applications fetching large temporal result sets.
- Impact: Temporal conversion requires less Python object-construction overhead while preserving existing values and exceptions.
Reusable Result-Set Metadata (#796)
- What changed: Stable native column metadata is retained for the current result set and invalidated when the result changes.
- Who benefits: Applications fetching many rows from result sets with stable column types.
- Impact: Fetch paths avoid repeated column descriptions while public metadata and
sql_variantbehavior remain current.
Reduced Fetch Diagnostic Overhead (#809)
- What changed: Fetch diagnostics are captured while ODBC records are valid and reused instead of being rescanned after clean fetches.
- Who benefits: Applications that perform many fetch calls.
- Impact: Clean fetches perform less repeated diagnostic work without changing warning or error propagation.
Faster Integer Row Indexing (#822)
- What changed: Exact integer indexes use a direct
Row.__getitem__fast path. - Who benefits: Applications that frequently access Row values by position.
- Impact: Integer lookup avoids unnecessary type dispatch while preserving behavior for booleans, subclasses, slices, and column names.
Lower fetchval() Logging Overhead (#823)
- What changed:
fetchval()checks whether debug logging is enabled before dispatching debug messages. - Who benefits: Applications calling
fetchval()with debug logging disabled. - Impact: Scalar fetches avoid unnecessary logging calls while preserving return values and row-consumption behavior.
Bug Fixes
Reliable Windows Shutdown (#783)
- What changed: Prevented the static ODBC environment handle from being released after Python finalization.
- Who benefits: Windows applications using pooled or nonpooled connections.
- Impact: Process shutdown no longer risks a late ODBC environment access violation.
Preserved Leading BOM-Like Characters (#793)
- What changed: Bounded UTF-16 fetches now treat leading U+FEFF and U+FFFE code points as payload instead of byte-order markers.
- Who benefits: Applications storing text that begins with BOM-shaped Unicode characters.
- Impact: Fetch operations return the complete bounded text value across supported platforms (GitHub Issue #794).
Clean Pooled Connection State (#777)
- What changed: Physical connections are rolled back and restored to autocommit before returning to the pool.
- Who benefits: Applications that reuse pooled connections after commits, rollbacks, or connection close.
- Impact: Idle sessions no longer retain empty transactions, and connections that cannot be sanitized are discarded (GitHub Issue #754).
Safe Native Logging of Dynamic Metadata (#791)
- What changed: Dynamic native log values, including server-controlled Arrow column metadata, are passed through literal format strings.
- Who benefits: Applications that enable native driver logging.
- Impact: Dynamic metadata cannot be interpreted as a native printf-style format directive.
UDT Parameter Binding (#818)
- What changed: SQL Server UDT parameter identities are resolved through
SQLDescribeParambefore scalar or array binding. - Who benefits: Applications binding spatial or other UDT values, including typed NULLs and reused statements.
- Impact: UDT parameters receive the required metadata without adding a new public API (GitHub Issue #816).
Visible Unsupported Encoding Requests (#828)
- What changed: Valid
setencoding()requests that cannot be applied now emitUserWarninginstead of being silently ignored. - Who benefits: Applications requesting
SQL_CHAR, UTF-16BE, or another unsupported binding configuration. - Impact: Callers can detect that the effective encoding remains unchanged while supported defaults continue without warnings (GitHub Issue #825).
Bounded Bulk Copy Timeouts (#804)
- What changed: Positive sub-second bulk-copy timeouts are rounded to one second instead of being truncated to an unlimited timeout.
- Who benefits: Applications configuring short bulk-copy timeouts.
- Impact: A positive timeout remains bounded rather than silently becoming infinite. Rust source: microsoft/mssql-rs#374. Thanks @nos1dot618 for the contribution.
Safe Bulk Copy Identifiers (#804)
- What changed: Bulk-copy destinations, columns, and collations are parsed, quoted, escaped, and validated consistently.
- Who benefits: Applications using multipart names, temporary tables, custom metadata, or identifiers that require quoting.
- Impact: Valid identifiers are handled safely, while malformed components and collation tokens fail with a usage error. Rust source: microsoft/mssql-rs#550.