Opened 3 hours ago

Last modified 3 hours ago

#36675 new Bug

Oracle dialect depends on implementation detail which was changed in python-oracledb 3.4

Reported by: Anthony Tuininga Owned by:
Component: Database layer (models, ORM) Version: 5.2
Severity: Normal Keywords: oracle
Cc: Anthony Tuininga Triage Stage: Unreviewed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: yes UI/UX: no

Description

This issue was reported by a Django user with the upgrade to python-oracledb 3.4: https://github.com/oracle/python-oracledb/issues/544. The issue is that the Django Oracle dialect depended on an implementation detail which changed in python-oracledb 3.4.

The following patch addresses that and is fine for all supported versions of cx_Oracle and python-oracledb:

diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 3b37c38f97..71089c1166 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -438,7 +438,7 @@ class OracleParam:
                 param = 0
         if hasattr(param, "bind_parameter"):
             self.force_bytes = param.bind_parameter(cursor)
-        elif isinstance(param, (Database.Binary, datetime.timedelta)):
+        elif isinstance(param, (bytes, datetime.timedelta)):
             self.force_bytes = param
         else:
             # To transmit to the database, we need Unicode if supported

Change History (1)

in reply to:  description comment:1 by Anthony Tuininga, 3 hours ago

A more comprehensive patch (also safe for all supported versions of cx_Oracle and python-oracledb):

diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 3b37c38f97..71089c1166 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -438,7 +438,7 @@ class OracleParam:
                 param = 0
         if hasattr(param, "bind_parameter"):
             self.force_bytes = param.bind_parameter(cursor)
-        elif isinstance(param, (Database.Binary, datetime.timedelta)):
+        elif isinstance(param, (bytes, datetime.timedelta)):
             self.force_bytes = param
         else:
             # To transmit to the database, we need Unicode if supported
diff --git a/django/db/backends/oracle/operations.py b/django/db/backends/oracle/operations.py
index 59eecdba20..14c69a59ff 100644
--- a/django/db/backends/oracle/operations.py
+++ b/django/db/backends/oracle/operations.py
@@ -273,12 +273,12 @@ END;
         return value
 
     def convert_datefield_value(self, value, expression, connection):
-        if isinstance(value, Database.Timestamp):
+        if isinstance(value, datetime.datetime):
             value = value.date()
         return value
 
     def convert_timefield_value(self, value, expression, connection):
-        if isinstance(value, Database.Timestamp):
+        if isinstance(value, datetime.datetime):
             value = value.time()
         return value
 
diff --git a/django/db/backends/oracle/utils.py b/django/db/backends/oracle/utils.py
index 57d97b3f77..d69414240c 100644
--- a/django/db/backends/oracle/utils.py
+++ b/django/db/backends/oracle/utils.py
@@ -24,7 +24,7 @@ class InsertVar:
         "BooleanField": int,
         "FloatField": Database.DB_TYPE_BINARY_DOUBLE,
         "DateTimeField": Database.DB_TYPE_TIMESTAMP,
-        "DateField": Database.Date,
+        "DateField": datetime.date,
         "DecimalField": decimal.Decimal,
     }
Note: See TracTickets for help on using tickets.
Back to Top