Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Each release of the mssql-python driver introduces new features, performance improvements, and bug fixes. The following sections detail every version.
mssql-python 1.11.0
Release date: July 2026
Enhancements
Improved context manager semantics
with connection: now properly commits transactions on clean exit and rolls back on exception, making it more Pythonic and predictable.
import mssql_python
# On clean exit, transaction commits
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("INSERT INTO MyTable (Name) VALUES ('Alice')")
# Automatically committed on exit
# On exception, transaction rolls back
try:
with mssql_python.connect(connection_string) as conn:
cursor = conn.cursor()
cursor.execute("INSERT INTO MyTable (Name) VALUES ('Bob')")
raise ValueError("Oops!")
except ValueError:
pass
# Changes rolled back on exit
Bug fixes
- Fixed a GIL-deadlock in the ODBC teardown path (
conn.close()andcursor.close()) and inSQLDescribeParamforNone-valued parameters in SSH-tunnel and in-process forwarder setups. - Fixed
BINARYandVARBINARYNULL parameters in temp tables and table variables. When automatic type resolution fails, the driver now emits a Python warning with explicitcursor.setinputsizes()guidance. - Fixed
import mssql_pythonfailing on Apple Silicon with a clean install (regression in 1.8.0). The bundled ODBC dylib dependencies are now rewritten for botharm64andx86_64architectures. - Fixed a GIL-deadlock in the Rust core that froze bulk copy operations when authenticating with
Authentication=ActiveDirectoryServicePrincipal.
mssql-python 1.10.0
Release date: June 2026
Enhancements
ActiveDirectoryServicePrincipal support for bulk copy
cursor.bulkcopy() now supports Authentication=ActiveDirectoryServicePrincipal, allowing bulk inserts by using service principal credentials.
import mssql_python
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryServicePrincipal;"
"UID=<application-client-id>;"
"PWD=<client-secret>;"
"Encrypt=yes"
)
cursor = conn.cursor()
cursor.execute("CREATE TABLE ##SpDemo (ID INT, Value FLOAT)")
conn.commit()
result = cursor.bulkcopy("##SpDemo", [(1, 1.5), (2, 2.5)])
print(f"Copied {result['rows_copied']} rows")
Bug fixes
- Fixed non-ASCII
VARCHARandCHARdata in the Arrow fetch path. - Fixed connection timeouts during bulk load operations.
mssql-python 1.9.0
Release date: June 2026
Enhancements
Row objects in bulk copy
cursor.bulkcopy() now accepts fetched Row objects directly instead of requiring manual tuple conversion.
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
# Fetch rows from source table
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product")
rows = cursor.fetchall()
# Pass fetched Row objects directly to bulkcopy
cursor.execute("CREATE TABLE ##RowBulkDemo (ProductID INT, Name NVARCHAR(50), ListPrice MONEY)")
conn.commit()
result = cursor.bulkcopy("##RowBulkDemo", rows)
print(f"Copied {result['rows_copied']} rows")
Bug fixes
- Fixed wheel packaging so
simdutfis always statically linked. - Fixed large
DECIMALinserts inexecutemany(). - Fixed incorrect type fallback for NULL parameters.
- Fixed exception pickle and unpickle round-trips.
- Fixed
nextset()so it preservesPRINTmessages across result sets. - Fixed
Rowhandling in theexecutemany()data-at-execution fallback path. - Fixed fetch method type checking for static analysis tools.
mssql-python 1.8.0
Release date: May 2026
Enhancements
ActiveDirectoryMSI support for bulk copy
cursor.bulkcopy() now supports Authentication=ActiveDirectoryMSI for system-assigned and user-assigned managed identities.
import mssql_python
# System-assigned managed identity
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryMSI;"
"Encrypt=yes"
)
cursor = conn.cursor()
cursor.execute("CREATE TABLE ##MsiDemo (ID INT, Name NVARCHAR(50))")
conn.commit()
result = cursor.bulkcopy("##MsiDemo", [(1, "Alice"), (2, "Bob")])
print(f"Copied {result['rows_copied']} rows")
Row string-key indexing
You can now access row values by column name, for example row["col"], in addition to positional indexing and attribute access.
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID = 1")
row = cursor.fetchone()
# Access by column name (new in 1.8.0)
print(row["ProductID"]) # Access by key
print(row["Name"])
# Still supports positional indexing
print(row[0]) # Positional access
# And attribute access
print(row.Name) # Attribute access
Bundled ODBC driver upgrade
The bundled Microsoft ODBC Driver for SQL Server was updated to 18.6.2.1.
Bug fixes
- Fixed deferred connect-attribute lifetime problems in token-based authentication.
- Fixed repeated connection string parsing in the authentication path.
- Fixed
executemany()type annotations for sequence inputs.
mssql-python 1.7.1
Release date: May 2026
Enhancements
Expanded wheel coverage and performance improvements
This release adds RHEL 8 compatible wheels, restores macOS Python 3.10 universal2 wheels, improves UTF-16 handling through simdutf, and optimizes the execute() hot path.
Performance impact: Batch execution throughput improves by ~15% on typical workloads due to hot path optimizations in the execute() method.
Bug fixes
- Fixed login failures so they raise
mssql_pythonDB-API exceptions instead ofRuntimeError. - Extended GIL release across blocking ODBC execution, fetch, transaction, and connection attribute calls.
- Fixed
executemany()failures when decimal values change sign. - Fixed inconsistent CP1252
VARCHARdecoding across platforms. - Fixed
cursor.bulkcopy()failures for empty strings inNVARCHAR(MAX)andVARCHAR(MAX)columns.
Note
Version 1.7.0 was withdrawn due to publication issues. Use version 1.7.1 or later.
mssql-python 1.6.0
Release date: April 2026
Enhancements
Parser-based connection string sanitization
This enhancement ensures correct parsing of special characters in password fields and braced values.
import mssql_python
# Complex passwords with special characters now parse correctly
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"UID=user@contoso;"
"PWD={p@ssw0rd;with{braces}};" # Braced values now handled correctly
"Encrypt=yes"
)
Connection string sanitization moved from regex-based logic to parser-based processing for correct handling of ODBC connection string syntax.
Bug fixes
- Fixed GIL release during blocking ODBC connect and disconnect operations.
- Fixed
setinputsizes()crashes withSQL_DECIMALandSQL_NUMERIChints. - Fixed incorrect
fetchone()behavior for ODBC catalog methods. - Fixed invalid cursor state errors when
reset_cursor=Falseis used. - Fixed
executemany()type hints for mapping-based parameter sequences. - Added a path traversal guard for
setup_logging(log_file_path=...).
mssql-python 1.5.0
Release date: April 2026
New features
Apache Arrow fetch support
Three new cursor methods provide high-performance columnar data retrieval through the Arrow C Data Interface:
cursor.arrow()returns a completepyarrow.Table.cursor.arrow_batch()returns a singlepyarrow.RecordBatch.cursor.arrow_reader()returns apyarrow.RecordBatchReaderfor streaming.
The implementation bypasses Python object creation in the hot path for improved performance. For complete documentation, see Apache Arrow integration.
sql_variant type support
The driver now detects sql_variant columns at fetch time, resolves their underlying base type, and returns correctly typed Python values instead of raw bytes.
Note
sql_variant columns use a streaming fetch path, which might have a slight performance impact compared to fixed-type columns.
Native UUID support
A new native_uuid setting controls whether UNIQUEIDENTIFIER columns are returned as uuid.UUID objects (default) or as pyodbc-compatible uppercase strings. Configure it at the module level or per connection:
# Module-level default
settings = mssql_python.get_settings()
settings.native_uuid = True # default
# Per-connection override
conn = mssql_python.connect(connection_string, native_uuid=False)
For more information, see Module configuration.
Row class public export
The Row class is now exported at the top level for type annotations:
from mssql_python import Row
Bug fixes
- Fixed false positive
?detection inside bracketed identifiers, string literals, and comments. - Fixed NULL parameter binding for
VARBINARYcolumns (no longer raises implicit conversion errors). - Fixed
datetime.timevalues losing microseconds on round-trips forTIME(1)throughTIME(7)columns. - Fixed Arrow fetch path to correctly include fractional seconds for
TIMEcolumns. - Fixed bulk copy with Microsoft Entra ID authentication methods (stale credential fields no longer cause validation errors).
- Cached Azure Identity credential instances at module level for improved authentication performance.
mssql-python 1.4.0
Release date: March 2025
New features
Bulk copy support
High-performance bulk data loading is now available through cursor.bulkcopy():
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
cursor.execute("CREATE TABLE ##BulkDemo (ID INT, Name NVARCHAR(50), Price DECIMAL(10,2))")
conn.commit()
data = [
(1, "Item 1", 10.50),
(2, "Item 2", 20.75),
# ... potentially millions of rows
]
result = cursor.bulkcopy("##BulkDemo", data)
print(f"Copied {result['rows_copied']} rows")
The method accepts options for batch_size, timeout, column_mappings, keep_identity, check_constraints, table_lock, keep_nulls, fire_triggers, and use_internal_transaction.
See Bulk copy for complete documentation.
Improvements
- Performance optimizations for large result sets.
- Reduced memory usage during batch operations.
- Enhanced error messages for bulk copy failures.
mssql-python 1.3.0
Release date: January 2025
New features
Settings class
Configure module-wide behavior through the new Settings class:
import mssql_python
settings = mssql_python.get_settings()
settings.lowercase = True # Lowercase column names in cursor.description
See Module configuration for details.
Improvements
- Better handling of connection timeout during Azure SQL failover.
- Improved compatibility with Python 3.13.
mssql-python 1.2.0
Release date: November 2024
New features
Schema discovery methods
New cursor methods for database metadata exploration:
cursor = conn.cursor()
# List all tables
cursor.tables(schema="dbo")
# Get column information
cursor.columns(table="Product", schema="Production")
# Get primary keys
cursor.primaryKeys(table="Product", schema="Production")
# Get foreign key relationships
cursor.foreignKeys(table="SalesOrderDetail", schema="Sales")
# Get stored procedures
cursor.procedures(schema="dbo")
# Get index statistics
cursor.statistics(table="Product", schema="Production")
# Get type information
cursor.getTypeInfo()
See Schema discovery for complete documentation.
Improvements
- Enhanced metadata caching for repeated schema queries.
- Better handling of computed columns in
columns()results.
mssql-python 1.1.0
Release date: September 2024
New features
Custom output converters
Register custom functions to transform column values during fetch:
import mssql_python
from decimal import Decimal
conn = mssql_python.connect(connection_string)
# Convert decimals to float (converter receives Decimal)
def decimal_to_float(value):
if value is None:
return None
return float(value) # value is already a Decimal object
conn.add_output_converter(mssql_python.SQL_DECIMAL, decimal_to_float)
# Custom money formatting
def format_money(value):
if value is None:
return "$0.00"
return f"${float(value):,.2f}" # value is already a Decimal object
conn.add_output_converter(mssql_python.SQL_DECIMAL, format_money)
Management methods:
add_output_converter(sql_type, converter_func)get_output_converter(sql_type)remove_output_converter(sql_type)clear_output_converters()
For complete documentation, see Custom type converters.
Improvements
- Better error messages for type conversion failures.
- Support for converter functions that return
None.
mssql-python 1.0.0
Release date: July 2024
Initial GA release
The first general availability release of mssql-python, Microsoft's native Python driver for SQL Server.
Core features
- DDBC architecture: Direct Database Connectivity without requiring ODBC driver installation.
- DB-API 2.0 compliance: Standard Python database interface.
- Connection pooling: Built-in connection pool management.
- Microsoft Entra authentication: Full support for Azure identity-based authentication.
- TLS encryption: Secure connections with certificate validation.
Connection features
- 21 connection string keywords.
- 9 authentication modes (SQL, Windows, and 7 Microsoft Entra ID methods).
- Autocommit control.
- Execution methods:
execute(),executemany(), andbatch_execute(). - Connection attributes through
set_attr()andgetinfo(). - Context manager support.
Cursor features
- Standard fetch methods:
fetchone(),fetchmany(),fetchall(). - Extended methods:
fetchval(),skip(). - Execution methods:
execute()andexecutemany(). - Row objects with attribute and index access.
- Multiple result set navigation with
nextset().
Data type support
- All SQL Server native types.
- Python↔SQL type mappings.
- SQL type constants for explicit typing (for example,
mssql_python.SQL_DECIMAL). - NULL handling as Python
None.
Transaction support
- Manual commit and rollback.
- Autocommit mode.
- Isolation level control.
- Deadlock detection and handling.
Authentication modes
| Mode | Description |
|---|---|
| SQL Server authentication | Username and password |
| Windows authentication | Trusted_Connection |
| ActiveDirectoryDefault | DefaultAzureCredential |
| ActiveDirectoryInteractive | Browser-based sign-in |
| ActiveDirectoryDeviceCode | Device code flow |
| ActiveDirectoryPassword | Microsoft Entra username and password (deprecated; uses ROPC) |
| ActiveDirectoryMSI | Managed identity |
| ActiveDirectoryServicePrincipal | Service principal |
| ActiveDirectoryIntegrated | Windows Kerberos |
Upgrade
From pyodbc
For detailed migration guidance, see Migrate from pyodbc.
Key differences:
- Both
?(qmark) and%(name)s(pyformat) parameter styles are supported. Your existing?queries work without changes. - No
callproc()method. UseEXECUTEstatements instead. - Built-in connection pooling.
- No external ODBC driver dependency.
From pymssql
For detailed migration guidance, see Migrate from pymssql.
Key differences:
- Replace
%sand%dparameter markers with?or%(name)s. - Use a connection string instead of positional arguments.
- No FreeTDS dependency.
- Multiple concurrent cursors per connection.
- Row objects with attribute access replace
as_dict=True.
Between mssql-python versions
Upgrade the driver to get new features and fixes.
pip install --upgrade mssql-python
Check the release notes for any breaking changes before upgrading production systems.
Roadmap
For upcoming features and the development roadmap, see the GitHub repository.