mssql-python 1.17.0 is now available, with more reliable bulk copy, faster connection pool reuse and recovery, accurate nextset() row counts, and PEP 249 Timestamp() compatibility.
mssql-python 1.17.0 is now available. This release is mostly about reliability. Bulk copy works better after upgrades, connection pools recover from dead connections, multi-statement batches report the right row counts, and Timestamp() works the way PEP 249 describes.
pip install --upgrade mssql-python
More reliable bulk copy
bulkcopy() and bulkcopy_arrow() get several fixes in this release:
- Works after package upgrades. Bulk copy no longer fails after you upgrade the package.
- Correct UTF-8 handling. Unicode text now lands in SQL Server unchanged.
- Early validation of destination names. Unsupported table names now fail up front with a clear error, instead of failing later in a confusing way.
- Full datetime precision. High-precision temporal values are no longer silently truncated.
These changes matter most if you load Unicode or high-precision timestamp data, or run pipelines that upgrade dependencies regularly.
Faster connection pool reuse
Clean pooled connections now go back into the pool and get reused with less redundant cleanup, and transaction safety is unchanged. Apps that check out and return connections often should see less overhead.
Recovering from dead pooled connections
Before this release, checking out a pooled connection that had stopped responding (for example, after a network drop) could hang for many minutes. Checkout now gives up after the configured login timeout and opens a new connection, so your app recovers predictably.
Accurate nextset() row counts
Cursor.nextset() now updates rowcount for each data-modification result and resets it for results that return rows. Previously, every result reported the count from the first statement.
cursor.execute("""
UPDATE dbo.Orders SET Status = 'Shipped' WHERE Region = 'West';
DELETE FROM dbo.OrderStaging WHERE Processed = 1;
""")
print(cursor.rowcount) # rows updated
cursor.nextset()
print(cursor.rowcount) # rows deleted, no longer the UPDATE count
This fix helps if you run stored procedures, multi-statement batches, or T-SQL loops.
PEP 249 Timestamp() compatibility
The microsecond argument to Timestamp() is now optional and defaults to 0. The standard six-argument DB-API call no longer raises a TypeError:
from mssql_python import Timestamp
ts = Timestamp(2026, 11, 3, 9, 0, 0)
Thank you, contributors
Thanks to the community members who contributed to this release: @Jhonatas2, @oscarrobertson, @phelipelui, and @austinaviv. We appreciate every issue, repro, and pull request.