summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorMariusz Felisiak <felisiak.mariusz@gmail.com>2020-06-30 09:50:15 +0200
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2020-06-30 09:56:14 +0200
commit21e8f9f7c96c97e42a301e53acbfd6cb6f1a7227 (patch)
tree8854e618dea51a619861fc9052c9ef3eff0870a4 /django
parentd1ff7c50e3a9815804818ef8f76ad3c16d3f1da4 (diff)
[3.0.x] Fixed #31751 -- Fixed database introspection with cx_Oracle 8.
Backport of 615e32162ff646db3456b90fb4eaaecc33dd3e4e from master
Diffstat (limited to 'django')
-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
3 files changed, 46 insertions, 18 deletions
diff --git a/django/contrib/gis/db/backends/oracle/introspection.py b/django/contrib/gis/db/backends/oracle/introspection.py
index 5e71c84fdd..80899b33d7 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. Of course,
# 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 86650a894e..ec993bbcfd 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -311,6 +311,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 2322ae0b5d..1ad0c9e8d7 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',))
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]