FEAT: datetimeoffset support in executemany()#260
Merged
gargsaumya merged 9 commits intomainfrom Sep 29, 2025
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive support for the SQL Server DATETIMEOFFSET type in both Python and C++ layers, enabling timezone-aware datetime handling in executemany() operations and regular queries. It introduces new SQL constants, enhances datetime parsing logic to handle timezone information, and implements proper parameter binding and data fetching for DATETIMEOFFSET values.
- Adds
SQL_DATETIMEOFFSETandSQL_C_SS_TIMESTAMPOFFSETconstants to support the new SQL type - Implements timezone-aware datetime parsing and type mapping logic
- Removes unused helper method and refactors
executemanytype inference logic
Reviewed Changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| mssql_python/constants.py | Adds SQL constants for DATETIMEOFFSET support |
| mssql_python/cursor.py | Enhances datetime parsing and type mapping, removes unused method |
| mssql_python/pybind/ddbc_bindings.cpp | Implements C++ DateTimeOffset struct, parameter binding, and data fetching |
| tests/test_004_cursor.py | Adds comprehensive tests for DATETIMEOFFSET functionality |
| tests/test_003_connection.py | Removes unused import statements |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
bewithgaurav
requested changes
Sep 26, 2025
sumitmsft
reviewed
Sep 29, 2025
sumitmsft
reviewed
Sep 29, 2025
sumitmsft
reviewed
Sep 29, 2025
sumitmsft
reviewed
Sep 29, 2025
Closed
e1253f2 to
5f45001
Compare
978fe43 to
41c1592
Compare
41c1592 to
93df1a2
Compare
📊 Code Coverage Report
Diff CoverageDiff: main...HEAD, staged and unstaged changes
Summary
mssql_python/pybind/ddbc_bindings.cppLines 1946-1965 1946 for (size_t i = 0; i < paramSetSize; ++i) {
1947 const py::handle& param = columnValues[i];
1948
1949 if (param.is_none()) {
! 1950 std::memset(&dtoArray[i], 0, sizeof(DateTimeOffset));
! 1951 strLenOrIndArray[i] = SQL_NULL_DATA;
1952 } else {
1953 if (!py::isinstance(param, datetimeType)) {
! 1954 ThrowStdException(MakeParamMismatchErrorStr(info.paramCType, paramIndex));
! 1955 }
1956
1957 py::object tzinfo = param.attr("tzinfo");
1958 if (tzinfo.is_none()) {
! 1959 ThrowStdException("Datetime object must have tzinfo for SQL_C_SS_TIMESTAMPOFFSET at paramIndex " +
! 1960 std::to_string(paramIndex));
! 1961 }
1962
1963 // Populate the C++ struct directly from the Python datetime object.
1964 dtoArray[i].year = static_cast<SQLSMALLINT>(param.attr("year").cast<int>());
1965 dtoArray[i].month = static_cast<SQLUSMALLINT>(param.attr("month").cast<int>());Lines 1982-1990 1982 }
1983 dataPtr = dtoArray;
1984 bufferLength = sizeof(DateTimeOffset);
1985 break;
! 1986 }
1987 case SQL_C_NUMERIC: {
1988 SQL_NUMERIC_STRUCT* numericArray = AllocateParamBufferArray<SQL_NUMERIC_STRUCT>(tempBuffers, paramSetSize);
1989 strLenOrIndArray = AllocateParamBufferArray<SQLLEN>(tempBuffers, paramSetSize);
1990 for (size_t i = 0; i < paramSetSize; ++i) {Lines 3223-3234 3223 );
3224 py_dt = py_dt.attr("astimezone")(datetime.attr("timezone").attr("utc"));
3225 row.append(py_dt);
3226 } else {
! 3227 row.append(py::none());
! 3228 }
3229 break;
! 3230 }
3231 case SQL_GUID: {
3232 SQLGUID* guidValue = &buffers.guidBuffers[col - 1][i];
3233 uint8_t reordered[16];
3234 reordered[0] = ((char*)&guidValue->Data1)[3];📋 Files Needing Attention📉 Files with overall lowest coverage (click to expand)mssql_python.pybind.ddbc_bindings.cpp: 67.4%
mssql_python.pybind.connection.connection.cpp: 68.3%
mssql_python.ddbc_bindings.py: 68.5%
mssql_python.pybind.connection.connection_pool.cpp: 78.9%
mssql_python.cursor.py: 79.1%
mssql_python.connection.py: 81.7%
mssql_python.helpers.py: 84.7%
mssql_python.auth.py: 85.3%
mssql_python.type.py: 86.8%
mssql_python.pooling.py: 88.8%🔗 Quick Links
|
bewithgaurav
approved these changes
Sep 29, 2025
sumitmsft
approved these changes
Sep 29, 2025
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Work Item / Issue Reference
Summary
This pull request adds comprehensive support for the SQL Server
DATETIMEOFFSETtype in both the Python and C++ layers of the codebase. It introduces new constants, enhances the datetime parsing logic to handle timezone-aware datetimes, and updates the parameter binding and data fetching logic to correctly handleDATETIMEOFFSETvalues. The changes ensure accurate round-trip of timezone-aware datetime values between Python and SQL Server.Support for DATETIMEOFFSET type:
SQL_DATETIMEOFFSETandSQL_C_SS_TIMESTAMPOFFSETconstants to bothmssql_python/constants.pyand the C++ bindings (ddbc_bindings.cpp). [1] [2]DateTimeOffsetC++ struct and integrated it into buffer management for column data. [1] [2] [3]datetimeobjects asDATETIMEOFFSET, including array binding forexecutemany. [1] [2] [3]DATETIMEOFFSETcolumns, ensuring Python receives timezone-awaredatetimeobjects in UTC. [1] [2] [3]Datetime parsing and mapping improvements:
_parse_datetimeinmssql_python/cursor.pyto support parsing timezone-aware datetime strings, improving compatibility withDATETIMEOFFSET.datetimeobjects, mapping the latter toDATETIMEOFFSET.Refactoring and cleanup:
_select_best_sample_valuestatic method frommssql_python/cursor.pyas type inference is now handled differently.executemanyto use the new_compute_column_typemethod, aligning with the improved datetime handling.