summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-06-30 09:50:15 +0200
committerGitHub <noreply@github.com>2020-06-30 09:50:15 +0200
commit615e32162ff646db3456b90fb4eaaecc33dd3e4e (patch)
treee9798236fefd04963aa90e603b26ae46652524eb
parenta93425a37f4defdb31d4ca96bb3bf6da21f0b5ce (diff)
Fixed #31751 -- Fixed database introspection with cx_Oracle 8.
-rw-r--r--django/contrib/gis/db/backends/oracle/introspection.py9
-rw-r--r--django/db/backends/oracle/base.py4
-rw-r--r--django/db/backends/oracle/introspection.py51
-rw-r--r--docs/releases/3.0.8.txt2
4 files changed, 48 insertions, 18 deletions
diff --git a/django/contrib/gis/db/backends/oracle/introspection.py b/django/contrib/gis/db/backends/oracle/introspection.py
index f97f0e1446..493fe74b46 100644
--- a/django/contrib/gis/db/backends/oracle/introspection.py
+++ b/django/contrib/gis/db/backends/oracle/introspection.py
@@ -1,14 +1,19 @@
import cx_Oracle
from django.db.backends.oracle.introspection import DatabaseIntrospection
+from django.utils.functional import cached_property
class OracleIntrospection(DatabaseIntrospection):
# Associating any OBJECTVAR instances with GeometryField. This won't work
# right on Oracle objects that aren't MDSYS.SDO_GEOMETRY, but it is the
# only object type supported within Django anyways.
- data_types_reverse = DatabaseIntrospection.data_types_reverse.copy()
- data_types_reverse[cx_Oracle.OBJECT] = 'GeometryField'
+ @cached_property
+ def data_types_reverse(self):
+ return {
+ **super().data_types_reverse,
+ cx_Oracle.OBJECT: 'GeometryField',
+ }
def get_geometry_type(self, table_name, description):
with self.connection.cursor() as cursor:
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index e104530228..10fff26fec 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -324,6 +324,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
return True
@cached_property
+ def cx_oracle_version(self):
+ return tuple(int(x) for x in Database.version.split('.'))
+
+ @cached_property
def oracle_version(self):
with self.temporary_connection():
return tuple(int(x) for x in self.connection.version.split('.'))
diff --git a/django/db/backends/oracle/introspection.py b/django/db/backends/oracle/introspection.py
index 3fab497b2a..41ffb68afb 100644
--- a/django/db/backends/oracle/introspection.py
+++ b/django/db/backends/oracle/introspection.py
@@ -6,29 +6,48 @@ from django.db import models
from django.db.backends.base.introspection import (
BaseDatabaseIntrospection, FieldInfo as BaseFieldInfo, TableInfo,
)
+from django.utils.functional import cached_property
FieldInfo = namedtuple('FieldInfo', BaseFieldInfo._fields + ('is_autofield', 'is_json'))
class DatabaseIntrospection(BaseDatabaseIntrospection):
- # Maps type objects to Django Field types.
- data_types_reverse = {
- cx_Oracle.BLOB: 'BinaryField',
- cx_Oracle.CLOB: 'TextField',
- cx_Oracle.DATETIME: 'DateField',
- cx_Oracle.FIXED_CHAR: 'CharField',
- cx_Oracle.FIXED_NCHAR: 'CharField',
- cx_Oracle.INTERVAL: 'DurationField',
- cx_Oracle.NATIVE_FLOAT: 'FloatField',
- cx_Oracle.NCHAR: 'CharField',
- cx_Oracle.NCLOB: 'TextField',
- cx_Oracle.NUMBER: 'DecimalField',
- cx_Oracle.STRING: 'CharField',
- cx_Oracle.TIMESTAMP: 'DateTimeField',
- }
-
cache_bust_counter = 1
+ # Maps type objects to Django Field types.
+ @cached_property
+ def data_types_reverse(self):
+ if self.connection.cx_oracle_version < (8,):
+ return {
+ cx_Oracle.BLOB: 'BinaryField',
+ cx_Oracle.CLOB: 'TextField',
+ cx_Oracle.DATETIME: 'DateField',
+ cx_Oracle.FIXED_CHAR: 'CharField',
+ cx_Oracle.FIXED_NCHAR: 'CharField',
+ cx_Oracle.INTERVAL: 'DurationField',
+ cx_Oracle.NATIVE_FLOAT: 'FloatField',
+ cx_Oracle.NCHAR: 'CharField',
+ cx_Oracle.NCLOB: 'TextField',
+ cx_Oracle.NUMBER: 'DecimalField',
+ cx_Oracle.STRING: 'CharField',
+ cx_Oracle.TIMESTAMP: 'DateTimeField',
+ }
+ else:
+ return {
+ cx_Oracle.DB_TYPE_DATE: 'DateField',
+ cx_Oracle.DB_TYPE_BINARY_DOUBLE: 'FloatField',
+ cx_Oracle.DB_TYPE_BLOB: 'BinaryField',
+ cx_Oracle.DB_TYPE_CHAR: 'CharField',
+ cx_Oracle.DB_TYPE_CLOB: 'TextField',
+ cx_Oracle.DB_TYPE_INTERVAL_DS: 'DurationField',
+ cx_Oracle.DB_TYPE_NCHAR: 'CharField',
+ cx_Oracle.DB_TYPE_NCLOB: 'TextField',
+ cx_Oracle.DB_TYPE_NVARCHAR: 'CharField',
+ cx_Oracle.DB_TYPE_NUMBER: 'DecimalField',
+ cx_Oracle.DB_TYPE_TIMESTAMP: 'DateTimeField',
+ cx_Oracle.DB_TYPE_VARCHAR: 'CharField',
+ }
+
def get_field_type(self, data_type, description):
if data_type == cx_Oracle.NUMBER:
precision, scale = description[4:6]
diff --git a/docs/releases/3.0.8.txt b/docs/releases/3.0.8.txt
index f23208f9ae..d702d75764 100644
--- a/docs/releases/3.0.8.txt
+++ b/docs/releases/3.0.8.txt
@@ -22,3 +22,5 @@ Bugfixes
* Fixed a regression in Django 3.0.2 that caused a migration crash on
PostgreSQL when adding a foreign key to a model with a namespaced
``db_table`` (:ticket:`31735`).
+
+* Added compatibility for ``cx_Oracle`` 8 (:ticket:`31751`).