Skip to content

Commit fa182e8

Browse files
jarshwahakaariai
authored andcommitted
Fixed django#18465 -- Set date formats correctly on Oracle
Correctly configure NLS_SESSION_PARAMETERS to format Date and DateTime on Oracle backend. Thanks to Josh Smeaton for report & patch.
1 parent 05d333b commit fa182e8

File tree

2 files changed

+23
-5
lines changed

2 files changed

+23
-5
lines changed

django/db/backends/oracle/base.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -479,13 +479,19 @@ def _cursor(self):
479479
del conn_params['use_returning_into']
480480
self.connection = Database.connect(conn_string, **conn_params)
481481
cursor = FormatStylePlaceholderCursor(self.connection)
482+
# Set the territory first. The territory overrides NLS_DATE_FORMAT
483+
# and NLS_TIMESTAMP_FORMAT to the territory default. When all of
484+
# these are set in single statement it isn't clear what is supposed
485+
# to happen.
486+
cursor.execute("ALTER SESSION SET NLS_TERRITORY = 'AMERICA'")
482487
# Set oracle date to ansi date format. This only needs to execute
483488
# once when we create a new connection. We also set the Territory
484-
# to 'AMERICA' which forces Sunday to evaluate to a '1' in TO_CHAR().
485-
cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
486-
" NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'"
487-
" NLS_TERRITORY = 'AMERICA'"
488-
+ (" TIME_ZONE = 'UTC'" if settings.USE_TZ else ''))
489+
# to 'AMERICA' which forces Sunday to evaluate to a '1' in
490+
# TO_CHAR().
491+
cursor.execute(
492+
"ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'"
493+
" NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'"
494+
+ (" TIME_ZONE = 'UTC'" if settings.USE_TZ else ''))
489495

490496
if 'operators' not in self.__dict__:
491497
# Ticket #14149: Check whether our LIKE implementation will

tests/regressiontests/backends/tests.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,18 @@ def test_client_encoding(self):
6666
self.assertEqual(connection.connection.encoding, "UTF-8")
6767
self.assertEqual(connection.connection.nencoding, "UTF-8")
6868

69+
@unittest.skipUnless(connection.vendor == 'oracle',
70+
"No need to check Oracle connection semantics")
71+
def test_order_of_nls_parameters(self):
72+
# an 'almost right' datetime should work with configured
73+
# NLS parameters as per #18465.
74+
c = connection.cursor()
75+
query = "select 1 from dual where '1936-12-29 00:00' < sysdate"
76+
# Test that the query succeeds without errors - pre #18465 this
77+
# wasn't the case.
78+
c.execute(query)
79+
self.assertEqual(c.fetchone()[0], 1)
80+
6981
class MySQLTests(TestCase):
7082
@unittest.skipUnless(connection.vendor == 'mysql',
7183
"Test valid only for MySQL")

0 commit comments

Comments
 (0)