Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions PyPI_Description.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,12 @@ PyBind11 provides:

We are currently in **Public Preview**.

## What's new in v0.12.0
## What's new in v0.13.0

- **Complex Data Type Support:** Added native support for DATETIMEOFFSET and UNIQUEIDENTIFIER data types with full round-trip handling, enabling seamless integration with Python's timezone-aware `datetime` objects and `uuid.UUID` types.
- **Support for monetary or currency values data types:** Extended MONEY and SMALLMONEY support to `executemany` operations with proper NULL handling and decimal conversion for improved bulk financial data processing.
- **Improved Database Metadata API:** Added `getinfo()` method with enhanced ODBC metadata retrieval, allowing users to query driver/data source information using ODBC info types.
- **Data Processing Optimizations:** Removed aggressive datetime parsing to prevent incorrect type conversions and improve data integrity across diverse datetime formats and string data.
- **Enhanced Batch Operations:** Complete support for UNIQUEIDENTIFIER and DATETIMEOFFSET in `executemany()` operations with automatic type inference, enabling efficient bulk inserts of complex data types including UUIDs and timezone-aware datetimes.
- **Streaming Large Values:** Robust handling of large objects (NVARCHAR/VARCHAR/VARBINARY(MAX)) in `executemany()` with automatic Data-At-Execution detection and fallback, supporting streaming inserts and fetches for massive datasets.
- **Improved Cursor Reliability:** Enhanced `cursor.rowcount` accuracy across all fetch operations, including proper handling of empty result sets and consistent behavior for SELECT, INSERT, and UPDATE operations.
- **Critical Stability Fixes:** Resolved memory leaks with secure token buffer handling, fixed resource cleanup to prevent segmentation faults during Python shutdown, and corrected type inference bugs in batch operations.

For more information, please visit the project link on Github: https://github.com/microsoft/mssql-python

Expand Down
14 changes: 12 additions & 2 deletions mssql_python/pybind/ddbc_bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2069,8 +2069,10 @@ SQLRETURN BindParameterArray(SQLHANDLE hStmt,
SQLGUID* guidArray = AllocateParamBufferArray<SQLGUID>(tempBuffers, paramSetSize);
strLenOrIndArray = AllocateParamBufferArray<SQLLEN>(tempBuffers, paramSetSize);

static py::module_ uuid_mod = py::module_::import("uuid");
static py::object uuid_class = uuid_mod.attr("UUID");
// Get cached UUID class from module-level helper
// This avoids static object destruction issues during Python finalization
py::object uuid_class = py::module_::import("mssql_python.ddbc_bindings").attr("_get_uuid_class")();

for (size_t i = 0; i < paramSetSize; ++i) {
const py::handle& element = columnValues[i];
std::array<unsigned char, 16> uuid_bytes;
Expand Down Expand Up @@ -3903,6 +3905,14 @@ PYBIND11_MODULE(ddbc_bindings, m) {
});


// Module-level UUID class cache
// This caches the uuid.UUID class at module initialization time and keeps it alive
// for the entire module lifetime, avoiding static destructor issues during Python finalization
m.def("_get_uuid_class", []() -> py::object {
static py::object uuid_class = py::module_::import("uuid").attr("UUID");
return uuid_class;
}, "Internal helper to get cached UUID class");

// Add a version attribute
m.attr("__version__") = "1.0.0";

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def finalize_options(self):

setup(
name='mssql-python',
version='0.12.0',
version='0.13.0',
description='A Python library for interacting with Microsoft SQL Server',
long_description=open('PyPI_Description.md', encoding='utf-8').read(),
long_description_content_type='text/markdown',
Expand Down
Loading