Blog Post

SQL Server Blog
2 MIN READ

mssql-python 1.17.0: more reliable bulk copy, faster pool recovery, and DB-API fixes

DavidLevy's avatar
DavidLevy
Icon for Microsoft rankMicrosoft
Nov 03, 2026

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.

Get started

Updated Nov 03, 2026
Version 1.0
No CommentsBe the first to comment