github microsoft/mssql-python v1.5.0

9 hours ago

Release Notes - Version 1.5.0

Enhancements

Apache Arrow Fetch Support (#354)

What changed: Added three new cursor methods — cursor.arrow(), cursor.arrow_batch(), and cursor.arrow_reader() — that convert SQL Server result sets into Apache Arrow data structures using the Arrow C Data Interface. The implementation bypasses Python object creation in the hot path for improved performance.
Who benefits: Data engineers and analysts working with analytics stacks such as pandas, Polars, DuckDB, or any Arrow-native framework; developers building high-throughput ETL pipelines requiring efficient columnar data exchange.
Impact: Enables zero-copy, native-speed data transfer from SQL Server to Arrow ecosystems; provides multiple consumption patterns to suit batch workloads.

PR #354 | GitHub Issue #130 - Thanks @ffelixg for the contribution!

sql_variant Type Support (#446)

What changed: Added native support for the SQL Server sql_variant type. The driver now detects sql_variant columns at fetch time, resolves their underlying base type, and returns correctly typed Python values. Updated constants, type validation, and C++ fetch routines to handle all valid sql_variant base types.
Who benefits: Applications querying tables that use sql_variant columns for flexible schema designs; developers migrating from other SQL Server drivers that support this type.
Impact: Eliminates unsupported type errors when querying sql_variant columns; ensures Python values match the actual stored base type. Note: sql_variant columns use a streaming fetch path, which may have a slight performance impact compared to fixed-type columns.

PR #446

Native UUID Support (#463)

What changed: Added a native_uuid setting (configurable at module and per-connection scope) that controls whether UNIQUEIDENTIFIER columns are returned as uuid.UUID objects (default) or as pyodbc-compatible uppercase strings. The connect() API accepts a native_uuid parameter for per-connection overrides.
Who benefits: Developers who prefer working with Python's uuid.UUID type directly; teams migrating from pyodbc who need string UUID compatibility; applications requiring consistent UUID handling across connections.
Impact: Eliminates manual UUID string-to-object conversions; provides a clean migration path from pyodbc-style string UUIDs; configurable at module level or per-connection for incremental adoption.

PR #463 | GitHub Issue #447

Row Class Public Export & Module API Improvements (#474)

What changed: The Row class is now exported at the top level of mssql_python. SQL type constants, GetInfo constants, and auth types are now dynamically exported from constants.py and importable directly from the package. Decimal separator logic was refactored into a dedicated decimal_config.py module.
Who benefits: Developers using type annotations that reference the Row class; users importing SQL type constants directly from the package; libraries building on top of mssql-python.
Impact: Enables from mssql_python import Row for type annotation use; reduces friction for users previously required to reach into internal modules; improves overall public API clarity.

PR #474 | GitHub Issue #270


Bug Fixes

False Positive qmark Detection in SQL Parameters (#465)

What changed: Fixed a bug where ? characters inside bracketed identifiers (e.g., [column?name]), single-quoted string literals, double-quoted identifiers, single-line comments, and multi-line comments were incorrectly treated as parameter placeholders, triggering spurious parameter mismatch errors. Added context-aware SQL scanning logic that correctly skips all quoted contexts.
Who benefits: Developers writing queries with bracketed identifiers containing ?; applications using generated SQL that includes ? in comments or string literals.
Impact: Eliminates false positive parameter mismatch errors; enables use of SQL Server identifiers containing ? without workarounds.

PR # #465 | GitHub Issue #464

NULL Parameter Type Mapping for VARBINARY Columns (#466)

What changed: Fixed a bug where inserting None (NULL) into a VARBINARY column raised an implicit conversion error from varchar to varbinary. NULL parameters were previously mapped to SQL_VARCHAR; changed to SQL_UNKNOWN_TYPE so the driver calls SQLDescribeParam to infer the correct target column type.
Who benefits: Applications that insert NULL values into VARBINARY or other binary columns; developers working with nullable binary data.
Impact: Eliminates implicit conversion errors for NULL VARBINARY parameters; ensures correct NULL binding for any column type without requiring explicit type hints.

PR #466 | GitHub Issue #458

Stale Auth Fields in Bulk Copy EntraID Authentication (#488)

What changed: Fixed a bug in cursor.bulkcopy() where stale connection-string credential fields (authentication, user_name, password) were left in the py-core context after an Azure AD access token was acquired. py-core's validator rejected access_token when combined with those fields. The fix strips them after token acquisition. Affects ActiveDirectoryDefault, ActiveDirectoryInteractive, and ActiveDirectoryDeviceCode.
Who benefits: Applications using bulk copy with Azure AD authentication methods.
Impact: Enables bulk copy to function correctly with all Azure AD authentication flows; eliminates validation rejections from py-core when using access token authentication.

PR #488

Credential Instance Cache for AAD Authentication (#483)

What changed: Fixed the AAD authentication flow to cache Azure Identity credential instances at module level rather than creating a new credential object on every token request. The cache is keyed by authentication type, protected by a lock for thread safety, and enables Azure Identity's built-in in-memory token cache.
Who benefits: Applications making frequent connections with EntraID authentication; services with high connection throughput relying on Azure AD tokens.
Impact: Reduces redundant token acquisition calls; enables token reuse through Azure Identity's in-memory cache; improves authentication performance for high-frequency connection scenarios.

PR #483 | GitHub Issue #388

datetime.time Values Losing Microseconds (#479)

What changed: Fixed a long-standing bug where datetime.time values fetched from SQL Server TIME/TIME2 columns had their microseconds attribute incorrectly set to zero. The fix transitions TIME/TIME2 handling from native C-type structs to text-based representations with full microsecond precision for both parameter binding and result fetching.
Who benefits: Applications storing and retrieving high-precision time values; developers working with time series data or audit logs requiring sub-second precision.
Impact: datetime.time values now correctly preserve microseconds on insert and select round-trips; eliminates silent data loss for TIME(1)–TIME(7) columns.

PR #479 | GitHub Issue #203

Arrow Fetch TIME Columns Missing Fractional Seconds (#499)

What changed: Fixed the Arrow fetch path to correctly include fractional seconds for SQL Server TIME columns. Arrow time columns are now represented as time64(ns) and include the fraction field from SQL_SS_TIME2_STRUCT in the computed nanosecond value.
Who benefits: Users of cursor.arrow(), cursor.arrow_batch(), and cursor.arrow_reader() fetching results containing TIME columns with sub-second precision.
Impact: Arrow fetches now correctly preserve TIME column fractional seconds; TIME(1)TIME(7) precision is fully retained; the Arrow time type is pa.time64("ns").

PR #499 | GitHub Issue #498 - Thanks @ffelixg for the contribution!

Explicit __all__ Exports from Main Module (#494)

What changed: Added an explicit __all__ list to init.py enumerating all public symbols. Any public object can now be imported directly from the root module without knowledge of the internal package structure, making the module fully mypy-compliant.
Who benefits: Developers using static type checkers (mypy, pylance, pyright); users following tutorial or documentation code snippets; libraries building on top of mssql-python.
Impact: Resolves mypy errors for direct imports from mssql_python; improves IDE autocompletion for module-level symbols; makes the public API surface explicit.

PR #494 | GitHub Issue #489 - Thanks @cepedus for the contribution!

Don't miss a new mssql-python release

NewReleases is sending notifications on new releases.