Skip to content

Commit 649f379

Browse files
committed
add type conversions for legacy drivers from string to datetime
1 parent b4b98e8 commit 649f379

File tree

1 file changed

+27
-2
lines changed

1 file changed

+27
-2
lines changed

sql_server/pyodbc/operations.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import datetime
22
import time
33
import uuid
4+
import warnings
45

56
from django.conf import settings
67
from django.db.backends.base.operations import BaseDatabaseOperations
@@ -34,6 +35,15 @@ def _get_utcoffset(self, tzname):
3435
delta = zone.localize(now, is_dst=False).utcoffset()
3536
return delta.days * 86400 + delta.seconds
3637

38+
def _warn_legacy_driver(self, sqltype):
39+
warnings.warn(
40+
'A %s value was received as a string. This is because you '
41+
'are now using a legacy ODBC driver which does not support '
42+
'this data type while your database has been migrated using it. '
43+
'You should upgrade your ODBC driver for consistency with your '
44+
'database migration.' % sqltype,
45+
RuntimeWarning)
46+
3747
def bulk_batch_size(self, fields, objs):
3848
"""
3949
Returns the maximum allowed batch size for the backend. The fields
@@ -95,13 +105,23 @@ def combine_expression(self, connector, sub_expressions):
95105

96106
def convert_datefield_value(self, value, expression, connection, context):
97107
if value is not None:
98-
if self.connection.use_legacy_datetime:
108+
# WDAC and old FreeTDS receive a date value as a string
109+
# http://blogs.msdn.com/b/sqlnativeclient/archive/2008/02/27/microsoft-sql-server-native-client-and-microsoft-sql-server-2008-native-client.aspx
110+
if isinstance(value, string_types):
111+
self._warn_legacy_driver('date')
112+
value = datetime.date(*map(lambda x: int(x), value.split('-')))
113+
elif self.connection.use_legacy_datetime:
99114
if isinstance(value, datetime.datetime):
100115
value = value.date() # extract date
101116
return value
102117

103118
def convert_datetimefield_value(self, value, expression, connection, context):
104119
if value is not None:
120+
# WDAC and old FreeTDS receive a datetime2 value as a string
121+
# http://blogs.msdn.com/b/sqlnativeclient/archive/2008/02/27/microsoft-sql-server-native-client-and-microsoft-sql-server-2008-native-client.aspx
122+
if isinstance(value, string_types):
123+
self._warn_legacy_driver('datetime2')
124+
value = datetime.datetime.strptime(value[:26], '%Y-%m-%d %H:%M:%S.%f')
105125
if settings.USE_TZ:
106126
value = timezone.make_aware(value, timezone.utc)
107127
return value
@@ -113,7 +133,12 @@ def convert_floatfield_value(self, value, expression, connection, context):
113133

114134
def convert_timefield_value(self, value, expression, connection, context):
115135
if value is not None:
116-
if self.connection.use_legacy_datetime:
136+
# WDAC and old FreeTDS receive a time value as a string
137+
# http://blogs.msdn.com/b/sqlnativeclient/archive/2008/02/27/microsoft-sql-server-native-client-and-microsoft-sql-server-2008-native-client.aspx
138+
if isinstance(value, string_types):
139+
self._warn_legacy_driver('time')
140+
value = datetime.time(*map(lambda x: int(x), value[:15].replace('.', ':').split(':')))
141+
elif self.connection.use_legacy_datetime:
117142
if (isinstance(value, datetime.datetime) and value.year == 1900 and value.month == value.day == 1):
118143
value = value.time() # extract time
119144
return value

0 commit comments

Comments
 (0)