diff options
| author | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-06-30 09:50:15 +0200 |
|---|---|---|
| committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2020-06-30 09:56:14 +0200 |
| commit | 21e8f9f7c96c97e42a301e53acbfd6cb6f1a7227 (patch) | |
| tree | 8854e618dea51a619861fc9052c9ef3eff0870a4 /django | |
| parent | d1ff7c50e3a9815804818ef8f76ad3c16d3f1da4 (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.py | 9 | ||||
| -rw-r--r-- | django/db/backends/oracle/base.py | 4 | ||||
| -rw-r--r-- | django/db/backends/oracle/introspection.py | 51 |
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] |
