11import datetime
22import time
33import uuid
4+ import warnings
45
56from django .conf import settings
67from 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