Skip to content

Commit bf6947f

Browse files
authored
Fixed migration issues from adding timezone support (microsoft#160)
* Fixed migration issues from adding timezone support * Changed assertEquals to assertEqual
1 parent e2fd494 commit bf6947f

File tree

3 files changed

+90
-2
lines changed

3 files changed

+90
-2
lines changed

mssql/base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
103103
'BooleanField': 'bit',
104104
'CharField': 'nvarchar(%(max_length)s)',
105105
'DateField': 'date',
106-
'DateTimeField': 'datetimeoffset',
106+
'DateTimeField': 'datetime2',
107107
'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
108108
'DurationField': 'bigint',
109109
'FileField': 'nvarchar(%(max_length)s)',
@@ -242,6 +242,9 @@ def __init__(self, *args, **kwargs):
242242
ops[op] = '%s COLLATE %s' % (sql, collation)
243243
self.operators.update(ops)
244244

245+
if (settings.USE_TZ):
246+
self.data_types['DateTimeField'] ='datetimeoffset'
247+
245248
def create_cursor(self, name=None):
246249
return CursorWrapper(self.connection.cursor(), self)
247250

mssql/introspection.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
4242
Database.SQL_TINYINT: 'SmallIntegerField',
4343
Database.SQL_TYPE_DATE: 'DateField',
4444
Database.SQL_TYPE_TIME: 'TimeField',
45+
Database.SQL_TYPE_TIMESTAMP: 'DateTimeField',
4546
SQL_TIMESTAMP_WITH_TIMEZONE: 'DateTimeField',
4647
Database.SQL_VARBINARY: 'BinaryField',
4748
Database.SQL_VARCHAR: 'TextField',

testapp/tests/test_timezones.py

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
# Licensed under the BSD license.
33

44
import datetime
5-
5+
from django.db import connection
66
from django.test import TestCase
7+
from django.test.utils import override_settings
78

89
from ..models import TimeZone
910

@@ -21,3 +22,86 @@ def test_iso_week_day(self):
2122
}
2223
for k, v in days.items():
2324
self.assertSequenceEqual(TimeZone.objects.filter(date__iso_week_day=k), [v])
25+
26+
class TestDateTimeToDateTimeOffsetMigration(TestCase):
27+
28+
def setUp(self):
29+
# Want this to be a naive datetime so don't want
30+
# to override settings before TimeZone creation
31+
self.time = TimeZone.objects.create()
32+
33+
def tearDown(self):
34+
TimeZone.objects.all().delete()
35+
36+
@override_settings(USE_TZ=True)
37+
def test_datetime_to_datetimeoffset_utc(self):
38+
dt = self.time.date
39+
40+
# Do manual migration from DATETIME2 to DATETIMEOFFSET
41+
# and local time to UTC
42+
with connection.schema_editor() as cursor:
43+
cursor.execute("""
44+
ALTER TABLE [testapp_timezone]
45+
ALTER COLUMN [date] DATETIMEOFFSET;
46+
47+
UPDATE [testapp_timezone]
48+
SET [date] = TODATETIMEOFFSET([date], 0) AT TIME ZONE 'UTC'
49+
""")
50+
51+
dto = TimeZone.objects.get(id=self.time.id).date
52+
53+
try:
54+
self.assertEqual(dt, dto.replace(tzinfo=None))
55+
finally:
56+
# Migrate back to DATETIME2 for other unit tests
57+
with connection.schema_editor() as cursor:
58+
cursor.execute("ALTER TABLE [testapp_timezone] ALTER column [date] datetime2")
59+
60+
@override_settings(USE_TZ=True, TIME_ZONE="Africa/Nairobi")
61+
def test_datetime_to_datetimeoffset_local_timezone(self):
62+
dt = self.time.date
63+
64+
# Do manual migration from DATETIME2 to DATETIMEOFFSET
65+
# and local time to UTC
66+
with connection.schema_editor() as cursor:
67+
cursor.execute("""
68+
ALTER TABLE [testapp_timezone]
69+
ALTER COLUMN [date] DATETIMEOFFSET;
70+
71+
UPDATE [testapp_timezone]
72+
SET [date] = TODATETIMEOFFSET([date], 180) AT TIME ZONE 'UTC'
73+
""")
74+
75+
dto = TimeZone.objects.get(id=self.time.id).date
76+
77+
try:
78+
# Africa/Nairobi (EAT) offset is +03:00
79+
self.assertEqual(dt - datetime.timedelta(hours=3), dto.replace(tzinfo=None))
80+
finally:
81+
# Migrate back to DATETIME2 for other unit tests
82+
with connection.schema_editor() as cursor:
83+
cursor.execute("ALTER TABLE [testapp_timezone] ALTER column [date] datetime2")
84+
85+
@override_settings(USE_TZ=True, TIME_ZONE="Africa/Nairobi")
86+
def test_datetime_to_datetimeoffset_other_timezone(self):
87+
dt = self.time.date
88+
89+
# Do manual migration from DATETIME2 to DATETIMEOFFSET
90+
# and local time to UTC
91+
with connection.schema_editor() as cursor:
92+
cursor.execute("""
93+
ALTER TABLE [testapp_timezone]
94+
ALTER COLUMN [date] DATETIMEOFFSET;
95+
96+
UPDATE [testapp_timezone]
97+
SET [date] = TODATETIMEOFFSET([date], 420) AT TIME ZONE 'UTC'
98+
""")
99+
100+
dto = TimeZone.objects.get(id=self.time.id).date
101+
102+
try:
103+
self.assertEqual(dt - datetime.timedelta(hours=7), dto.replace(tzinfo=None))
104+
finally:
105+
# Migrate back to DATETIME2 for other unit tests
106+
with connection.schema_editor() as cursor:
107+
cursor.execute("ALTER TABLE [testapp_timezone] ALTER column [date] datetime2")

0 commit comments

Comments
 (0)