Skip to content

Commit 80a6ac8

Browse files
committed
fix(sqlserver): normalize fractional seconds to 6 digits and introspect server version on connect
1 parent 36d5294 commit 80a6ac8

3 files changed

Lines changed: 18 additions & 8 deletions

File tree

‎src/rhosocial/activerecord/backend/impl/sqlserver/adapters.py‎

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,28 @@ def _parse_sql_datetime(value: str) -> datetime:
1919
ODBC/older Python runtimes deliver datetime2 values as strings without a
2020
``T`` separator and often carry seven fractional digits (100ns precision),
2121
e.g. ``'2026-08-09 05:25:26.5205700'``. Python's ``datetime.fromisoformat``
22-
rejects values with more than six fractional digits on Python < 3.13, so
23-
normalize the string first: normalize the separator, then drop any
24-
fractional component beyond six digits.
22+
only accepts three or six fractional digits on Python < 3.11, so normalize
23+
the string first: restore the ``T`` separator and pad the fractional
24+
component to exactly six digits.
2525
"""
2626
normalized = value.replace('Z', '+00:00')
2727
if 'T' not in normalized:
2828
head, sep, rest = normalized.partition(' ')
2929
if sep:
3030
normalized = f"{head}T{rest}"
31-
if '.' in normalized:
32-
head, sep, frac = normalized.rpartition('.')
33-
frac = frac.rstrip('0')[:6]
34-
if frac:
35-
normalized = f"{head}.{frac}"
31+
dot_pos = normalized.rfind('.')
32+
if dot_pos != -1:
33+
suffix = ''
34+
frac_end = len(normalized)
35+
for marker in ('+', '-'):
36+
idx = normalized.find(marker, dot_pos + 1)
37+
if idx != -1:
38+
frac_end = idx
39+
suffix = normalized[idx:]
40+
break
41+
frac = normalized[dot_pos + 1:frac_end]
42+
frac = frac[:6].ljust(6, '0')
43+
normalized = f"{normalized[:dot_pos]}.{frac}{suffix}"
3644
result = datetime.fromisoformat(normalized)
3745
if result.tzinfo is None:
3846
return result.replace(tzinfo=timezone.utc)

‎src/rhosocial/activerecord/backend/impl/sqlserver/async_backend.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@ async def connect(self) -> None:
201201
)
202202

203203
self.log(logging.INFO, "Async connection to SQL Server established")
204+
await self.introspect_and_adapt()
204205

205206
except Exception as e:
206207
self.log(logging.ERROR, f"Failed to connect to SQL Server: {str(e)}")

‎src/rhosocial/activerecord/backend/impl/sqlserver/backend.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ def connect(self) -> None:
248248
self._connection = pyodbc.connect(conn_str, **conn_args)
249249

250250
self.log(logging.INFO, "Connected to SQL Server database successfully")
251+
self.introspect_and_adapt()
251252

252253
except PyODBCError as e:
253254
self.log(logging.ERROR, f"Failed to connect to SQL Server: {str(e)}")

0 commit comments

Comments
 (0)