Muokkaa

What's new in mssql-python

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() and cursor.close()) and in SQLDescribeParam for None-valued parameters in SSH-tunnel and in-process forwarder setups.
  • Fixed BINARY and VARBINARY NULL parameters in temp tables and table variables. When automatic type resolution fails, the driver now emits a Python warning with explicit cursor.setinputsizes() guidance.
  • Fixed import mssql_python failing on Apple Silicon with a clean install (regression in 1.8.0). The bundled ODBC dylib dependencies are now rewritten for both arm64 and x86_64 architectures.
  • 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 VARCHAR and CHAR data 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 simdutf is always statically linked.
  • Fixed large DECIMAL inserts in executemany().
  • Fixed incorrect type fallback for NULL parameters.
  • Fixed exception pickle and unpickle round-trips.
  • Fixed nextset() so it preserves PRINT messages across result sets.
  • Fixed Row handling in the executemany() 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_python DB-API exceptions instead of RuntimeError.
  • Extended GIL release across blocking ODBC execution, fetch, transaction, and connection attribute calls.
  • Fixed executemany() failures when decimal values change sign.
  • Fixed inconsistent CP1252 VARCHAR decoding across platforms.
  • Fixed cursor.bulkcopy() failures for empty strings in NVARCHAR(MAX) and VARCHAR(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 with SQL_DECIMAL and SQL_NUMERIC hints.
  • Fixed incorrect fetchone() behavior for ODBC catalog methods.
  • Fixed invalid cursor state errors when reset_cursor=False is 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 complete pyarrow.Table.
  • cursor.arrow_batch() returns a single pyarrow.RecordBatch.
  • cursor.arrow_reader() returns a pyarrow.RecordBatchReader for 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 VARBINARY columns (no longer raises implicit conversion errors).
  • Fixed datetime.time values losing microseconds on round-trips for TIME(1) through TIME(7) columns.
  • Fixed Arrow fetch path to correctly include fractional seconds for TIME columns.
  • 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(), and batch_execute().
  • Connection attributes through set_attr() and getinfo().
  • Context manager support.

Cursor features

  • Standard fetch methods: fetchone(), fetchmany(), fetchall().
  • Extended methods: fetchval(), skip().
  • Execution methods: execute() and executemany().
  • 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. Use EXECUTE statements instead.
  • Built-in connection pooling.
  • No external ODBC driver dependency.

From pymssql

For detailed migration guidance, see Migrate from pymssql.

Key differences:

  • Replace %s and %d parameter 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.