[3.1.x] Fixed #31751 -- Fixed database introspection with cx_Oracle 8.
Backport of 615e32162f
from master
This commit is contained in:
parent
c944df827f
commit
3b5e307bbc
|
@ -1,14 +1,19 @@
|
||||||
import cx_Oracle
|
import cx_Oracle
|
||||||
|
|
||||||
from django.db.backends.oracle.introspection import DatabaseIntrospection
|
from django.db.backends.oracle.introspection import DatabaseIntrospection
|
||||||
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
|
|
||||||
class OracleIntrospection(DatabaseIntrospection):
|
class OracleIntrospection(DatabaseIntrospection):
|
||||||
# Associating any OBJECTVAR instances with GeometryField. This won't work
|
# Associating any OBJECTVAR instances with GeometryField. This won't work
|
||||||
# right on Oracle objects that aren't MDSYS.SDO_GEOMETRY, but it is the
|
# right on Oracle objects that aren't MDSYS.SDO_GEOMETRY, but it is the
|
||||||
# only object type supported within Django anyways.
|
# only object type supported within Django anyways.
|
||||||
data_types_reverse = DatabaseIntrospection.data_types_reverse.copy()
|
@cached_property
|
||||||
data_types_reverse[cx_Oracle.OBJECT] = 'GeometryField'
|
def data_types_reverse(self):
|
||||||
|
return {
|
||||||
|
**super().data_types_reverse,
|
||||||
|
cx_Oracle.OBJECT: 'GeometryField',
|
||||||
|
}
|
||||||
|
|
||||||
def get_geometry_type(self, table_name, description):
|
def get_geometry_type(self, table_name, description):
|
||||||
with self.connection.cursor() as cursor:
|
with self.connection.cursor() as cursor:
|
||||||
|
|
|
@ -323,6 +323,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def cx_oracle_version(self):
|
||||||
|
return tuple(int(x) for x in Database.version.split('.'))
|
||||||
|
|
||||||
@cached_property
|
@cached_property
|
||||||
def oracle_version(self):
|
def oracle_version(self):
|
||||||
with self.temporary_connection():
|
with self.temporary_connection():
|
||||||
|
|
|
@ -6,29 +6,48 @@ from django.db import models
|
||||||
from django.db.backends.base.introspection import (
|
from django.db.backends.base.introspection import (
|
||||||
BaseDatabaseIntrospection, FieldInfo as BaseFieldInfo, TableInfo,
|
BaseDatabaseIntrospection, FieldInfo as BaseFieldInfo, TableInfo,
|
||||||
)
|
)
|
||||||
|
from django.utils.functional import cached_property
|
||||||
|
|
||||||
FieldInfo = namedtuple('FieldInfo', BaseFieldInfo._fields + ('is_autofield', 'is_json'))
|
FieldInfo = namedtuple('FieldInfo', BaseFieldInfo._fields + ('is_autofield', 'is_json'))
|
||||||
|
|
||||||
|
|
||||||
class DatabaseIntrospection(BaseDatabaseIntrospection):
|
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
|
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):
|
def get_field_type(self, data_type, description):
|
||||||
if data_type == cx_Oracle.NUMBER:
|
if data_type == cx_Oracle.NUMBER:
|
||||||
precision, scale = description[4:6]
|
precision, scale = description[4:6]
|
||||||
|
|
|
@ -22,3 +22,5 @@ Bugfixes
|
||||||
* Fixed a regression in Django 3.0.2 that caused a migration crash on
|
* 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
|
PostgreSQL when adding a foreign key to a model with a namespaced
|
||||||
``db_table`` (:ticket:`31735`).
|
``db_table`` (:ticket:`31735`).
|
||||||
|
|
||||||
|
* Added compatibility for ``cx_Oracle`` 8 (:ticket:`31751`).
|
||||||
|
|
Loading…
Reference in New Issue