Skip to content

Commit 00fbc3c

Browse files
FIX: Revert "FEAT: Support for Native_UUID Attribute (#282)" (#314)
This reverts commit 10a8815. ### Work Item / Issue Reference <!-- IMPORTANT: Please follow the PR template guidelines below. For mssql-python maintainers: Insert your ADO Work Item ID below (e.g. AB#37452) For external contributors: Insert Github Issue number below (e.g. #149) Only one reference is required - either GitHub issue OR ADO Work Item. --> <!-- mssql-python maintainers: ADO Work Item --> > AB#<WORK_ITEM_ID> <!-- External contributors: GitHub Issue --> > GitHub Issue: #<ISSUE_NUMBER> ------------------------------------------------------------------- ### Summary <!-- Insert your summary of changes below. Minimum 10 characters required. --> This pull request refactors the global settings management and row handling logic for the `mssql_python` package. The main improvements include simplifying how global settings like `lowercase` and decimal separator are managed, removing the custom module class, and streamlining the `Row` object to reduce memory usage and complexity. The changes also clarify the output converter logic and remove redundant code related to settings snapshots and UUID handling. **Settings and Global Configuration Improvements:** * Replaced the custom module class and property-based settings management with a simpler global `Settings` object, protected by a threading lock, and a custom module-level `__setattr__` for direct attribute updates [[1]](diffhunk://#diff-d95f3a67986de29f30453416b1b4c34e6a43207e9a33e2b1b80ef0c378b0a538L6-R103) [[2]](diffhunk://#diff-d95f3a67986de29f30453416b1b4c34e6a43207e9a33e2b1b80ef0c378b0a538L177-R280) [[3]](diffhunk://#diff-d95f3a67986de29f30453416b1b4c34e6a43207e9a33e2b1b80ef0c378b0a538L253-L301). * Added new functions `setDecimalSeparator` and `getDecimalSeparator` for explicit decimal separator control, with input validation and C++ backend integration. **Row Object and Data Handling Simplification:** * Refactored the `Row` class to remove the settings snapshot and native UUID conversion logic, reducing per-row memory usage and complexity; column mapping is now optimized for future improvements [[1]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL8-R25) [[2]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL49-R60). * Updated cursor fetch methods (`fetchone`, `fetchmany`, `fetchall`) to no longer pass or rely on settings snapshots, simplifying their signatures and usage [[1]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L1973-R1964) [[2]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L2022-R2011) [[3]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L2063-R2051). **Output Converter Logic Cleanup:** * Streamlined output converter logic in the `Row` class, removing unnecessary integer byte size mapping and improving error handling and logging for converter exceptions [[1]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL171-L183) [[2]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL197-R106). **Cursor Execution and Description Handling:** * Cleaned up cursor execution logic by removing redundant settings snapshot and UUID index management, and ensuring description is initialized after execution for all result types [[1]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L1128-L1129) [[2]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L1138-R1150). (References: [[1]](diffhunk://#diff-d95f3a67986de29f30453416b1b4c34e6a43207e9a33e2b1b80ef0c378b0a538L6-R103) [[2]](diffhunk://#diff-d95f3a67986de29f30453416b1b4c34e6a43207e9a33e2b1b80ef0c378b0a538L177-R280) [[3]](diffhunk://#diff-d95f3a67986de29f30453416b1b4c34e6a43207e9a33e2b1b80ef0c378b0a538L253-L301) [[4]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL8-R25) [[5]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL49-R60) [[6]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL171-L183) [[7]](diffhunk://#diff-ebcc43b610c4574e22237098f80f57ce0b1c6ef1d0a1264a28667622beb1d21eL197-R106) [[8]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L1128-L1129) [[9]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L1138-R1150) [[10]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L1973-R1964) [[11]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L2022-R2011) [[12]](diffhunk://#diff-deceea46ae01082ce8400e14fa02f4b7585afb7b5ed9885338b66494f5f38280L2063-R2051) <!-- ### 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 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 --> --------- Co-authored-by: Gaurav Sharma <sharmag@microsoft.com>
1 parent 7938b26 commit 00fbc3c

File tree

7 files changed

+90
-455
lines changed

7 files changed

+90
-455
lines changed

eng/pipelines/pr-validation-pipeline.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -313,11 +313,12 @@ jobs:
313313
distroName: 'Ubuntu-SQL2025'
314314
sqlServerImage: 'mcr.microsoft.com/mssql/server:2025-latest'
315315
useAzureSQL: 'false'
316-
Ubuntu_AzureSQL:
317-
dockerImage: 'ubuntu:22.04'
318-
distroName: 'Ubuntu-AzureSQL'
319-
sqlServerImage: ''
320-
useAzureSQL: 'true'
316+
${{ if ne(variables['AZURE_CONNECTION_STRING'], '') }}:
317+
Ubuntu_AzureSQL:
318+
dockerImage: 'ubuntu:22.04'
319+
distroName: 'Ubuntu-AzureSQL'
320+
sqlServerImage: ''
321+
useAzureSQL: 'true'
321322
Debian:
322323
dockerImage: 'debian:12'
323324
distroName: 'Debian'

mssql_python/__init__.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
Licensed under the MIT license.
44
This module initializes the mssql_python package.
55
"""
6-
76
import sys
87
import types
98
from typing import Dict
@@ -174,7 +173,6 @@ def pooling(max_size: int = 100, idle_timeout: int = 600, enabled: bool = True)
174173
else:
175174
PoolingManager.enable(max_size, idle_timeout)
176175

177-
178176
_original_module_setattr = sys.modules[__name__].__setattr__
179177

180178
# Export SQL constants at module level
@@ -251,22 +249,8 @@ def get_info_constants() -> Dict[str, int]:
251249
"""
252250
return {name: member.value for name, member in GetInfoConstants.__members__.items()}
253251

254-
255252
# Create a custom module class that uses properties instead of __setattr__
256253
class _MSSQLModule(types.ModuleType):
257-
@property
258-
def native_uuid(self) -> bool:
259-
"""Get the native UUID setting."""
260-
return _settings.native_uuid
261-
262-
@native_uuid.setter
263-
def native_uuid(self, value: bool) -> None:
264-
"""Set the native UUID setting."""
265-
if not isinstance(value, bool):
266-
raise ValueError("native_uuid must be a boolean value")
267-
with _settings_lock:
268-
_settings.native_uuid = value
269-
270254
@property
271255
def lowercase(self) -> bool:
272256
"""Get the lowercase setting."""
@@ -297,5 +281,4 @@ def lowercase(self, value: bool) -> None:
297281
sys.modules[__name__] = new_module
298282

299283
# Initialize property values
300-
lowercase: bool = _settings.lowercase
301-
native_uuid: bool = _settings.native_uuid
284+
lowercase: bool = _settings.lowercase

mssql_python/cursor.py

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,8 +1125,6 @@ def execute( # pylint: disable=too-many-locals,too-many-branches,too-many-state
11251125
# After successful execution, initialize description if there are results
11261126
column_metadata = []
11271127
try:
1128-
# ODBC specification guarantees that column metadata is available immediately after
1129-
# a successful SQLExecute/SQLExecDirect for the first result set
11301128
ddbc_bindings.DDBCSQLDescribeCol(self.hstmt, column_metadata)
11311129
self._initialize_description(column_metadata)
11321130
except Exception as e: # pylint: disable=broad-exception-caught
@@ -1135,30 +1133,21 @@ def execute( # pylint: disable=too-many-locals,too-many-branches,too-many-state
11351133

11361134
# Reset rownumber for new result set (only for SELECT statements)
11371135
if self.description: # If we have column descriptions, it's likely a SELECT
1138-
# Capture settings snapshot for this result set
1139-
settings = get_settings()
1140-
self._settings_snapshot = { # pylint: disable=attribute-defined-outside-init
1141-
"lowercase": settings.lowercase,
1142-
"native_uuid": settings.native_uuid,
1143-
}
1144-
# Identify UUID columns based on Python type in description[1]
1145-
# This relies on _map_data_type correctly mapping SQL_GUID to uuid.UUID
1146-
self._uuid_indices = [] # pylint: disable=attribute-defined-outside-init
1147-
for i, desc in enumerate(self.description):
1148-
if desc and desc[1] == uuid.UUID: # Column type code at index 1
1149-
self._uuid_indices.append(i)
1150-
# Verify we have complete description tuples (7 items per PEP-249)
1151-
elif desc and len(desc) != 7:
1152-
log(
1153-
"warning",
1154-
f"Column description at index {i} has incorrect tuple length: {len(desc)}",
1155-
)
11561136
self.rowcount = -1
11571137
self._reset_rownumber()
11581138
else:
11591139
self.rowcount = ddbc_bindings.DDBCSQLRowCount(self.hstmt)
11601140
self._clear_rownumber()
11611141

1142+
# After successful execution, initialize description if there are results
1143+
column_metadata = []
1144+
try:
1145+
ddbc_bindings.DDBCSQLDescribeCol(self.hstmt, column_metadata)
1146+
self._initialize_description(column_metadata)
1147+
except Exception as e:
1148+
# If describe fails, it's likely there are no results (e.g., for INSERT)
1149+
self.description = None
1150+
11621151
self._reset_inputsizes() # Reset input sizes after execution
11631152
# Return self for method chaining
11641153
return self
@@ -1971,8 +1960,7 @@ def fetchone(self) -> Union[None, Row]:
19711960

19721961
# Create and return a Row object, passing column name map if available
19731962
column_map = getattr(self, "_column_name_map", None)
1974-
settings_snapshot = getattr(self, "_settings_snapshot", None)
1975-
return Row(self, self.description, row_data, column_map, settings_snapshot)
1963+
return Row(self, self.description, row_data, column_map)
19761964
except Exception as e: # pylint: disable=broad-exception-caught
19771965
# On error, don't increment rownumber - rethrow the error
19781966
raise e
@@ -2019,9 +2007,8 @@ def fetchmany(self, size: Optional[int] = None) -> List[Row]:
20192007

20202008
# Convert raw data to Row objects
20212009
column_map = getattr(self, "_column_name_map", None)
2022-
settings_snapshot = getattr(self, "_settings_snapshot", None)
20232010
return [
2024-
Row(self, self.description, row_data, column_map, settings_snapshot)
2011+
Row(self, self.description, row_data, column_map)
20252012
for row_data in rows_data
20262013
]
20272014
except Exception as e: # pylint: disable=broad-exception-caught
@@ -2060,9 +2047,8 @@ def fetchall(self) -> List[Row]:
20602047

20612048
# Convert raw data to Row objects
20622049
column_map = getattr(self, "_column_name_map", None)
2063-
settings_snapshot = getattr(self, "_settings_snapshot", None)
20642050
return [
2065-
Row(self, self.description, row_data, column_map, settings_snapshot)
2051+
Row(self, self.description, row_data, column_map)
20662052
for row_data in rows_data
20672053
]
20682054
except Exception as e: # pylint: disable=broad-exception-caught
@@ -2471,4 +2457,4 @@ def setoutputsize(self, size: int, column: Optional[int] = None) -> None:
24712457
This method is a no-op in this implementation as buffer sizes
24722458
are managed automatically by the underlying driver.
24732459
"""
2474-
# This is a no-op - buffer sizes are managed automatically
2460+
# This is a no-op - buffer sizes are managed automatically

mssql_python/helpers.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -328,14 +328,12 @@ class Settings:
328328
Settings class for mssql_python package configuration.
329329
330330
This class holds global settings that affect the behavior of the package,
331-
including lowercase column names, decimal separator, and native UUID handling.
331+
including lowercase column names, decimal separator.
332332
"""
333333
def __init__(self) -> None:
334334
self.lowercase: bool = False
335335
# Use the pre-determined separator - no locale access here
336336
self.decimal_separator: str = _default_decimal_separator
337-
self.native_uuid: bool = False # Default to False for backwards compatibility
338-
339337

340338
# Global settings instance
341339
_settings: Settings = Settings()
@@ -345,4 +343,4 @@ def __init__(self) -> None:
345343
def get_settings() -> Settings:
346344
"""Return the global settings object"""
347345
with _settings_lock:
348-
return _settings
346+
return _settings

0 commit comments

Comments
 (0)