mssql-python 1.14.0 is now available on PyPI. This release moves the standard parameter detection and execution path into native C++, improving throughput for wide parameterized statements and batched workloads. It also corrects connection timeout behavior, prevents Decimal conversion errors from exposing parameter values, and fixes several Arrow, bulk copy, and Windows ARM64 issues.
pip install –upgrade mssql-python
Highlights
Parameter detection and execution move into C++
Every parameterized execute() call has to identify each Python value, choose the corresponding SQL and C types, bind the values, and call SQLExecute. Previously, mssql-python performed type detection in a Python loop, constructed a ParamInfo object for every parameter, and passed those objects across the pybind11 boundary before the native layer could bind and execute the statement.
In 1.14.0, the standard path performs detection, binding, and execution in one native C++ pipeline and one Python-to-native call. Type checks use the CPython API directly, and the parameter metadata stays in C++.
The improvement grows with the number of parameters in each call. Benchmarks recorded in PR #549 measured type detection at about 35 ns per parameter, down from 2.0 to 2.3 microseconds. For statements with 50 or more parameters, execute() was about 21% to 73% faster across the tested macOS ARM64 and Linux ARM64 environments.
The same PR measured these complete insert workloads on macOS ARM64. These figures include the network round trip and SQL Server writing the rows, not just driver overhead.
| Workload | Before | After | Speedup |
|---|---|---|---|
| Orders: integer, varchar, decimal, datetime2 | 880.6 ms | 561.0 ms | 1.57x |
| Events: UUID, datetime2, varchar, integer | 827.2 ms | 533.5 ms | 1.55x |
| Documents: nvarchar(max) around 10 KB | 1622.0 ms | 1021.3 ms | 1.59x |
| Wide rows: 50 mixed columns | 1598.6 ms | 1048.9 ms | 1.52x |
These are results from the PR benchmark environment, not a throughput guarantee. The gain depends on how much of each call was previously spent inspecting parameters. A benchmark that issued 5,000 single-row calls with four parameters showed no meaningful change because the network round trip dominated the roughly 9 microseconds of parameter detection that was removed.
Calls that use setinputsizes() continue through the existing Python detection path so their explicit type overrides are preserved. No API changes are required, but those calls do not receive this optimization yet.
connect(timeout=) now controls login time
The timeout argument to connect() is documented as a login timeout, consistent with pyodbc. Before 1.14.0, mssql-python silently stored it as the per-statement query timeout. It did not bound the connection attempt, and a later long-running query could be canceled after that number of seconds.
The two settings are now separate:
from mssql_python import connect
# Allow up to five seconds to establish the connection.
conn = connect(connection_string, timeout=5)
# Allow up to 60 seconds for each statement on this connection.
conn.timeout = 60
An explicit attrs_before[SQL_ATTR_LOGIN_TIMEOUT] still takes precedence over the timeout argument. Both timeout entry points reject negative values, non-integers, and booleans.
This is a behavior correction with an upgrade implication. If an application relied on connect(timeout=N) to stop long-running queries, set Connection.timeout = N explicitly after upgrading.
Decimal conversion errors no longer include parameter values
When executemany() could not convert a value for a Decimal or NUMERIC parameter, the exception included the entire parameter row. That row could contain names, email addresses, account data, or other sensitive values, and the exception could then be collected by an application log or APM service.
The error now reports only the row index, column index, and Python type:
Failed to convert parameter to Decimal at row 0, column 3 (value type: str)
The fix also prevents a value-bearing exception cause from reintroducing the data through a chained traceback.
See PR #719.
Arrow and bulk copy fixes
- Arrow View types: bulkcopy_arrow() now accepts variable-length Arrow View arrays, including Polars string_view columns exported directly through the Arrow C Data Interface. Values and NULLs round-trip without an explicit DataFrame.to_arrow() call. This support comes through mssql_py_core 0.1.9. See PR #717, PR #729, and issue #708.
- Original Arrow fetch errors are preserved: defensive cleanup in the Arrow batch reader no longer raises a secondary exception that hides the fetch failure callers need to diagnose. See PR #718 and issue #712.
- Unlimited bulk copy timeout: bulkcopy(timeout=0) now passes zero through as no timeout, matching the documented BCP contract. Negative, non-integer, and boolean values remain invalid. See PR #698 and issue #697.
Windows ARM64 extension loading
On Windows, platform.machine() reports the host CPU architecture rather than the architecture of the running Python interpreter. An x64 Python installation on a Windows ARM64 machine therefore looked for an ARM64 native extension even though pip had installed the win_amd64 wheel. Import still fell back to another file, but it performed the fallback on every import and printed a warning to stdout.
The loader now derives the architecture from the Python interpreter build, matching the wheel tag. Fallback notices use RuntimeWarning instead of writing to stdout.
See PR #727 and issue #726. Thanks to @Om-singhaI for the contribution.
Upgrading
For most users, upgrading requires no code changes:
pip install –upgrade mssql-python
Check these two cases:
- Code that used connect(timeout=N) as a query timeout must set conn.timeout = N explicitly. The constructor argument now controls the login attempt as documented.
- Calls with explicit setinputsizes() overrides retain their existing behavior but do not use the new native parameter detection path.
Full release notes are available on the mssql-python 1.14.0 release page. File issues and feature requests at github.com/microsoft/mssql-python/issues, or email us at mssql-python@microsoft.com.

