Skip to content

Tags: microsoft/mssql-python

Tags

v1.15.0

Toggle v1.15.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
FIX: Make SQL Server CI setup retry-safe (#780)

### Work Item / Issue Reference
<!-- mssql-python maintainers: ADO Work Item -->
>
[AB#47797](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/47797)

-------------------------------------------------------------------
### Summary

Replace duplicated Unix SQL-container setup with one shared,
ownership-aware helper and one bounded SQL-only retry, including macOS
SQL2025, Linux matrices, and coverage. Capture redacted failure evidence
before removing the failed container, recreate only job-owned
containers, bound readiness/commands/cleanup, and propagate cancellation
and permanent failure.

Keep dependency installation, native builds, and pytest outside the
retry boundary. Preserve macOS build/setup overlap, optional AzureSQL
behavior, existing ARM build retry settings, amd64 SQL containers, and
current database/image selections. Isolate final SQL cleanup from
test-container cleanup and retain safe image/state/log evidence without
publishing dumps or credentials.

The PR changes only the pipeline YAML and shared SQL setup helper. No
test files are added or modified. Verification uses temporary
development checks kept outside this PR, normal PR validation, and
separate hosted Linux/macOS SQL2025 recovery and permanent-failure
experiments. The local Windows x64/Python 3.13 native build and Black
gate passed. Hosted results and review feedback are being assessed; the
PR remains a draft.

This is recovery mitigation for observed SQL setup failures, not a fix
for the underlying SQL-engine crash or a guarantee that hosted failures
cannot recur.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

v1.14.0

Toggle v1.14.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
FIX: Fixing Build-Release-Package-Pipeline failure (#732)

### Work Item / Issue Reference  
<!-- 
IMPORTANT: Please follow the PR template guidelines below.
For mssql-python maintainers: Insert your ADO Work Item ID below 
For external contributors: Insert Github Issue number below
Only one reference is required - either GitHub issue OR ADO Work Item.
-->

<!-- mssql-python maintainers: ADO Work Item -->
>
[AB#47683](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/47683)

<!-- External contributors: GitHub Issue -->


-------------------------------------------------------------------
### Summary   
<!-- Insert your summary of changes below. Minimum 10 characters
required. -->
**Symptom**
Build-Release-Package-Pipeline failed on all four Linux variants during
Step 8 (pytest) with a collection-time error, before any test ran:
tests/test_fork_coverage_security.py:10: in <module>
    SPEC.loader.exec_module(coverage_comment)
E   FileNotFoundError: [Errno 2] No such file or directory:
'/test_isolated_cp310/.github/scripts/prepare_fork_coverage_comment.py'
!!! Interrupted: 1 error during collection !!!

Combined with --maxfail=1, this aborted cp310–cp314 on:

- Linux manylinux_2_28 x86_64
- Linux manylinux_2_28 aarch64
- Linux musllinux x86_64
- Linux musllinux aarch64

**Root cause**
Two independent design assumptions collided:

- Test-side assumption. [test_fork_coverage_security.py:7] resolves
helpers at module top level (collection time) via
[Path(__file__).parents[1] / ".github" / "scripts" /
"prepare_fork_coverage_comment.py"], and also reads
[forked-pr-coverage.yml] and [pr-code-coverage.yml]. It assumes
[parents[1]] is a full repo checkout.

Pipeline-side assumption. The Linux release lane in
[build-linux-single-stage.yml] intentionally runs pytest from an empty
isolated directory to prove the installed wheel is self-contained:

TEST_DIR="/test_isolated_${PYBIN}"
rm -rf $TEST_DIR; mkdir -p $TEST_DIR
$PY -m pip install -q "$WHEEL"
cp -r /workspace/tests $TEST_DIR/
cp /workspace/pytest.ini $TEST_DIR/
cp /workspace/requirements.txt $TEST_DIR/

Only [tests], [pytest.ini], [requirements.txt] are copied. [.github] is
not — until now no test needed anything outside [tests].
[test_fork_coverage_security.py] (added by the fork-coverage hardening
series culminating in PR #714) is the first test that reaches outside
[tests] at import time. In the isolated layout [parents[1]]=
/test_isolated_cp310/, so the .github/… lookup fell off the map. Only
the Linux lane runs the empty-isolated-dir model; Windows and macOS run
from $(Build.SourcesDirectory) (a real checkout), so they were
unaffected — and repo-root GitHub CI was unaffected too.

**Fix:**
Make the pipeline meet the test's assumption, and drop an earlier
stop-gap.

Change added to Linux release pipeline
Copy [.github] into $TEST_DIR alongside [tests], in both the manylinux
branch (covers x86_64 + aarch64) and the musllinux branch (covers x86_64
+ aarch64):

[build-linux-single-stage.yml:322] — manylinux bash -lc block:

[build-linux-single-stage.yml:392] — musllinux sh -lc block: same two
lines.

cp -r /workspace/tests $TEST_DIR/ || echo "WARNING: No tests directory";
Some tests read repo-side helper scripts/workflows (e.g.
.github/scripts/prepare_fork_coverage_comment.py).
cp -r /workspace/.github $TEST_DIR/ || echo "WARNING: No .github
directory";

These are the only two code sites reached by the four failing Linux
stages.
<!-- 
### PR Title Guide

> For feature requests
FEAT: (short-description)

> For non-feature requests like test case updates, config updates ,
dependency updates etc
CHORE: (short-description) 

> For Fix requests
FIX: (short-description)

> For doc update requests 
DOC: (short-description)

> For Formatting, indentation, or styling update
STYLE: (short-description)

> For Refactor, without any feature changes
REFACTOR: (short-description)

> For performance improvements
PERF: (short-description)

> For release related changes, without any feature changes
RELEASE: #<RELEASE_VERSION> (short-description) 

### Contribution Guidelines

External contributors:
- Create a GitHub issue first:
https://github.com/microsoft/mssql-python/issues/new
- Link the GitHub issue in the "GitHub Issue" section above
- Follow the PR title format and provide a meaningful summary

mssql-python maintainers:
- Create an ADO Work Item following internal processes
- Link the ADO Work Item in the "ADO Work Item" section above  
- Follow the PR title format and provide a meaningful summary
-->

v1.13.0

Toggle v1.13.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
RELEASE:1.13.0 (#707)

### Work Item / Issue Reference

>
[AB#47087](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/47087)

-------------------------------------------------------------------
### Summary

Release mssql-python v1.13.0.

Version bump to 1.13.0. Updates `mssql_python/__init__.py`, `setup.py`,
`PyPI_Description.md`, and the README "Important Note" section. Bundled
`mssql_py_core` bumped from 0.1.7 to 0.1.8 (no source/API changes —
dev-nightly to stable pin).

#### Enhancements

- **ODBC driver ships exclusively via `mssql-python-odbc` (Phase 2)** —
The `libs/` fallback introduced in v1.12.0 has been removed.
`mssql-python` now hard-depends on `mssql-python-odbc==18.6.2.1`; `pip
install mssql-python` still pulls the driver package transparently.
Smaller wheels; driver binaries managed independently (#693).
- **Apache Arrow bulk copy** — New `Cursor.bulkcopy_arrow(table_name,
source)` method for high-performance bulk loading from `pyarrow.Table` /
`RecordBatch` / Arrow C Data Interface sources; classic `bulkcopy()` now
raises `TypeError` for Arrow inputs and steers users to the new method
(#665).
- **`token_provider=` parameter for Azure Identity credentials** —
`connect()` accepts any credential with a `.get_token(scope)` method
(`DefaultAzureCredential`, `AzureCliCredential`,
`ManagedIdentityCredential`, …). Mutually exclusive with
`Authentication=` in the connection string (#603, issue #577).
- **Identity-aware connection pooling with token-expiry refresh** — Pool
now keys on security context, preventing cross-identity connection
leaks; token acquisition deferred to pool-misses; connections with
near-expiry tokens refreshed automatically (#660, issues #651, #659).

#### Bug Fixes

- **Silent zero-row `executemany` batches on late NULLs** — Fixed
numeric array parameter binding paths
(`TINYINT`/`SMALLINT`/`INT`/`FLOAT`) that left indicator slots
uninitialized when a NULL appeared partway through the batch (#702,
issue #670).
- **`SQL_WVARCHAR` output converter applied as catch-all to non-string
columns** — Fallback now gated on `str`/`bytes` mapped types (#692,
issue #691).
- **Integer-keyed output converters silently never fired** —
`add_output_converter(SQL_DECIMAL, ...)` and other integer SQL type code
keys now dispatch correctly (pyodbc parity) (#690, issue #684).
- **`RecordBatchReader.Close()` for Arrow result sets** —
`Cursor.arrow_reader()` now returns a wrapper whose `.close()` releases
server-side resources and leaves the parent cursor usable (#644, issue
#643).
- **`AttributeError` in `Cursor.__del__` on partially-initialized
cursor** — `__init__` sets `closed`/`hstmt` before any raise; `__del__`
uses correct `sys.is_finalizing()` guard (#646, issue #642).

#### Version Bump

- `mssql_python/__init__.py`: `__version__ = "1.13.0"`
- `setup.py`: `version="1.13.0"`
- `PyPI_Description.md`: `## What's new in v1.13.0` section refreshed
- `README.md`: "Important Note" updated for Phase 2 (no more `libs/`
fallback, `mssql-python-odbc==18.6.2.1`)

v1.12.0

Toggle v1.12.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
CHORE: Bump mssql-py-core to 0.1.7 (#688)

### Work Item / Issue Reference

> AB#<WORK_ITEM_ID>
#667 

-------------------------------------------------------------------
### Summary

Bump the bundled `mssql-py-core` version from `0.1.6` to `0.1.7`.

Updates `eng/versions/mssql-py-core.version`, which pins the Rust
`mssql_py_core`
wheel that PR validation and release pipelines download from NuGet.

v1.11.0

Toggle v1.11.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
CHORE: Bump mssql-py-core to 0.1.6 (#666)

### Work Item / Issue Reference

> GitHub Issue: #662

-------------------------------------------------------------------
### Summary

Bumps the bundled `mssql-py-core` pin from `0.1.5` to `0.1.6`, which
includes the Rust-side GIL-deadlock fix for Service Principal bulk copy
(mssql-rs #78). Fixes the freeze reported in #662 (related: #623).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

v1.10.0

Toggle v1.10.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
RELEASE:1.10.0 (#648)

[AB#45983](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/45983)

Release mssql-python v1.10.0.

This PR bumps the driver version from 1.9.0 to 1.10.0 across
`mssql_python/__init__.py`, `setup.py`, and updates
`PyPI_Description.md` with this release's customer-facing changes.

### Summary

**Enhancements**

- **Active Directory Service Principal support for Bulk Copy**
([#576](#576)) -
`bulkcopy` now supports
`Authentication=ActiveDirectoryServicePrincipal`, registering a
token-provider callback that resolves the tenant from the STS URL
mid-handshake and returns a service-principal JWT.

**Bug Fixes**

- **Non-ASCII VARCHAR data in the Arrow fetch path**
([#575](#575)) - The Arrow
fetch path now requests `SQL_CHAR` data as `SQL_C_WCHAR` (UTF-16LE),
ensuring correct decoding regardless of encoding settings, locale, or
OS. Thanks @ffelixg for the contribution!
- **Bulk load connection timeouts**
([#641](#641)) - Fixed
connection timeouts during bulk load operations. Fix lands in the Rust
core via bumping `mssql_py_core` from 0.1.4 to 0.1.5. *(via
`mssql_py_core`)*

**Version bump**

- `mssql_python/__init__.py`: `__version__ = "1.10.0"`
- `setup.py`: `version="1.10.0"`
- `PyPI_Description.md`: updated `## What's new in v1.10.0` section

v1.9.0

Toggle v1.9.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
RELEASE:1.9.0 (#633)

[AB#45750](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/45750)

Release mssql-python v1.9.0. Bumps `__version__`, `setup.py` version,
and updates `PyPI_Description.md` with this release's customer-facing
changes.

### Summary

#### Enhancements
- **Row Objects in Bulk Copy** - `bulkcopy` now accepts `Row` objects
(and lists) directly, converting each row to a tuple automatically
(#615).
- **Cached Parameter Type Resolution for NULLs** - `SQLDescribeParam`
results are cached per statement when binding `NULL` parameters,
removing redundant server round-trips and fixing incorrect type
fallbacks for all-NULL columns and VARBINARY types (#614).

#### Bug Fixes
- **macOS / Linux Import Failure** - simdutf is now always statically
linked via FetchContent, fixing import/symbol failures on machines
without simdutf at the CI build path (#608). Resolves #607, #628.
- **executemany Large Decimal Handling** - Fixed a `SQL_C_NUMERIC` type
mismatch when inserting `Decimal` values outside the SQL Server `MONEY`
range via `executemany` (#611). Resolves #609.
- **Exception Pickling** - DB-API exception subclasses and
`ConnectionStringParseError` now implement `__reduce__` for correct
pickle/unpickle round-trips (#616). Resolves #587.
- **PRINT Messages in nextset()** - Diagnostic messages from subsequent
result sets are captured on `SQL_SUCCESS_WITH_INFO` during `nextset()`
(#618). Resolves #612.
- **Row Objects in executemany DAE Path** - `executemany` converts `Row`
objects to tuples in the DAE fallback path, fixing `varchar(max)` writes
(#630). Resolves #629.
- **Static Type-Checking of Fetch Methods** -
`fetchone`/`fetchmany`/`fetchall` are no longer reassigned as instance
attributes, fixing type-checking under `ty` (#631). Resolves #620.

#### Version bump
- `mssql_python/__init__.py`: `__version__` 1.8.0 → 1.9.0
- `setup.py`: version 1.8.0 → 1.9.0
- `PyPI_Description.md`: updated "What's new" section to v1.9.0

Bundled `mssql_py_core` version unchanged (0.1.4).

v1.8.0

Toggle v1.8.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
RELEASE: 1.8.0 (#605)

[AB#43993](https://sqlclientdrivers.visualstudio.com/c6d89619-62de-46a0-8b46-70b92a84d85e/_workitems/edit/43993)

### Summary

Release mssql-python v1.8.0.

### Enhancements
- **ActiveDirectoryMSI Support for Bulk Copy** (#573)
- **Row String-Key Indexing** (#589)
- **Bundled ODBC Driver Upgrade** from 18.5.1.1 to 18.6.2.1 (#569)

### Bug Fixes
- **Deferred Connect-Attribute Use-After-Free** (#596) - Fixes #594,
#597
- **Connection String Parsed Multiple Times in Auth Path** (#590) -
Fixes #580
- **executemany Type Annotation Regression** (#586) - Fixes #572

### Version Bump
- `__version__` → 1.8.0 in `__init__.py` and `setup.py`
- `PyPI_Description.md` updated with v1.8.0 release notes

v1.7.1

Toggle v1.7.1's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
RELEASE:1.7.1 (#593)

### Work Item / Issue Reference

>
[AB#45159](https://sqlclientdrivers.visualstudio.com/mssql-python/_sprints/taskboard/mssql-python%20Team/mssql-python/Rubidium/May%202026?workitem=45159)

-------------------------------------------------------------------
### Summary

**Enhancements**
- #548 — manylinux_2_28 build targets for RHEL 8 / glibc 2.28
- #542 — macOS universal2 wheel for Python 3.10
- #526 — UTF-16 string handling via simdutf
- #528 — Optimized execute() hot path
- #567 — Azure Linux installation docs

**Bug Fixes**
- #562 — Login failures now raise mssql_python exception instead of
RuntimeError
- #568 — GIL released during blocking SQLSetConnectAttr calls
- #541 — GIL released during blocking ODBC statement/fetch/transaction
calls
- #560 — executemany RuntimeError when decimals change signs
- #495 — Inconsistent CP1252 VARCHAR retrieval Windows vs Linux
- #559 — BulkCopy empty string in NVARCHAR(MAX)/VARCHAR(MAX) (via
mssql_py_core 0.1.4)

v1.7.0

Toggle v1.7.0's commit message

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
RELEASE:1.7.1 (#593)

### Work Item / Issue Reference

>
[AB#45159](https://sqlclientdrivers.visualstudio.com/mssql-python/_sprints/taskboard/mssql-python%20Team/mssql-python/Rubidium/May%202026?workitem=45159)

-------------------------------------------------------------------
### Summary

**Enhancements**
- #548 — manylinux_2_28 build targets for RHEL 8 / glibc 2.28
- #542 — macOS universal2 wheel for Python 3.10
- #526 — UTF-16 string handling via simdutf
- #528 — Optimized execute() hot path
- #567 — Azure Linux installation docs

**Bug Fixes**
- #562 — Login failures now raise mssql_python exception instead of
RuntimeError
- #568 — GIL released during blocking SQLSetConnectAttr calls
- #541 — GIL released during blocking ODBC statement/fetch/transaction
calls
- #560 — executemany RuntimeError when decimals change signs
- #495 — Inconsistent CP1252 VARCHAR retrieval Windows vs Linux
- #559 — BulkCopy empty string in NVARCHAR(MAX)/VARCHAR(MAX) (via
mssql_py_core 0.1.4)