Skip to content

Commit ba19ba7

Browse files
committed
Fix executemany SQL_C_NUMERIC mismatch for Decimal values outside MONEY range (GH-609)
The executemany auto-detection path set paramCType=SQL_C_NUMERIC for Decimal values outside the MONEY range, but the conversion loop converts all Decimals to strings. The C extension then received strings where it expected NumericData structs, raising RuntimeError. Fixed by overriding SQL_C_NUMERIC to SQL_C_CHAR in the auto-detection path, matching the existing GH-503 fix in the setinputsizes path. Fixes #609
2 parents 3cd4fea + d3ba6d1 commit ba19ba7

4 files changed

Lines changed: 14 additions & 29 deletions

File tree

‎OneBranchPipelines/variables/common-variables.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ variables:
1616

1717
# Python versions to build
1818
- name: PYTHON_VERSIONS
19-
value: '3.10,3.11,3.12,3.13'
19+
value: '3.10,3.11,3.12,3.13,3.14'
2020

2121
# Package name
2222
- name: PACKAGE_NAME

‎eng/pipelines/pr-validation-pipeline.yml‎

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -469,16 +469,18 @@ jobs:
469469
SQL2022:
470470
sqlServerImage: 'mcr.microsoft.com/mssql/server:2022-latest'
471471
sqlVersion: 'SQL2022'
472+
pythonVersion: '3.13'
472473
SQL2025:
473474
sqlServerImage: 'mcr.microsoft.com/mssql/server:2025-latest'
474475
sqlVersion: 'SQL2025'
476+
pythonVersion: '3.14'
475477

476478
steps:
477479
- task: UsePythonVersion@0
478480
inputs:
479-
versionSpec: '3.13'
481+
versionSpec: '$(pythonVersion)'
480482
addToPath: true
481-
displayName: 'Use Python 3.13 on macOS'
483+
displayName: 'Use Python $(pythonVersion) on macOS'
482484

483485
- script: |
484486
brew update
@@ -640,18 +642,18 @@ jobs:
640642
strategy:
641643
matrix:
642644
Ubuntu:
643-
dockerImage: 'ubuntu:22.04'
645+
dockerImage: 'ubuntu:24.04'
644646
distroName: 'Ubuntu'
645647
sqlServerImage: 'mcr.microsoft.com/mssql/server:2022-latest'
646648
useAzureSQL: 'false'
647649
Ubuntu_SQL2025:
648-
dockerImage: 'ubuntu:22.04'
650+
dockerImage: 'ubuntu:24.04'
649651
distroName: 'Ubuntu-SQL2025'
650652
sqlServerImage: 'mcr.microsoft.com/mssql/server:2025-latest'
651653
useAzureSQL: 'false'
652654
${{ if ne(variables['AZURE_CONNECTION_STRING'], '') }}:
653655
Ubuntu_AzureSQL:
654-
dockerImage: 'ubuntu:22.04'
656+
dockerImage: 'ubuntu:24.04'
655657
distroName: 'Ubuntu-AzureSQL'
656658
sqlServerImage: ''
657659
useAzureSQL: 'true'
@@ -741,8 +743,8 @@ jobs:
741743
export DEBIAN_FRONTEND=noninteractive
742744
743745
# Download the package to configure the Microsoft repo
744-
if [ '$(distroName)' = 'Ubuntu' ]; then
745-
curl -sSL -O https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
746+
if [[ '$(distroName)' =~ ^Ubuntu ]]; then
747+
curl -sSL -O https://packages.microsoft.com/config/ubuntu/24.04/packages-microsoft-prod.deb
746748
else
747749
# Debian 12
748750
curl -sSL -O https://packages.microsoft.com/config/debian/12/packages-microsoft-prod.deb
@@ -898,7 +900,7 @@ jobs:
898900
899901
# Add Microsoft repository
900902
curl -sSL https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
901-
curl -sSL https://packages.microsoft.com/config/ubuntu/22.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
903+
curl -sSL https://packages.microsoft.com/config/ubuntu/24.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
902904
903905
# Update package lists
904906
apt-get update -qq
@@ -1065,7 +1067,7 @@ jobs:
10651067
export DEBIAN_FRONTEND=noninteractive
10661068
10671069
# Download the package to configure the Microsoft repo
1068-
if [ '$(distroName)' = 'Ubuntu' ]; then
1070+
if [[ '$(distroName)' =~ ^Ubuntu ]]; then
10691071
curl -sSL -O https://packages.microsoft.com/config/ubuntu/22.04/packages-microsoft-prod.deb
10701072
else
10711073
# Debian 12

‎mssql_python/cursor.py‎

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3011,28 +3011,11 @@ def bulkcopy(
30113011
)
30123012
pycore_cursor = pycore_connection.cursor()
30133013

3014-
# Auto-convert Row/list objects to tuples for the Rust layer.
3015-
# mssql_py_core expects native tuples; Row objects (from fetchmany)
3016-
# are iterable but fail the strict type check in Rust.
3017-
from mssql_python.row import Row
3018-
3019-
def _ensure_tuples(iterable):
3020-
for item in iterable:
3021-
if isinstance(item, tuple):
3022-
yield item
3023-
elif isinstance(item, (list, Row)):
3024-
yield tuple(item)
3025-
else:
3026-
raise TypeError(
3027-
f"bulkcopy data rows must be tuples, lists, or Row objects, "
3028-
f"got {type(item).__name__}"
3029-
)
3030-
30313014
# Call bulkcopy with explicit keyword arguments
30323015
# The API signature: bulkcopy(table_name, data_source, batch_size=0, timeout=30, ...)
30333016
result = pycore_cursor.bulkcopy(
30343017
table_name,
3035-
_ensure_tuples(data),
3018+
iter(data),
30363019
batch_size=batch_size,
30373020
timeout=timeout,
30383021
column_mappings=column_mappings,

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.black]
22
line-length = 100
3-
target-version = ['py38', 'py39', 'py310', 'py311']
3+
target-version = ['py310', 'py311', 'py312', 'py313', 'py314']
44
include = '\.pyi?$'
55
extend-exclude = '''
66
/(

0 commit comments

Comments
 (0)