summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShai Berger <shai@platonix.com>2014-09-27 00:18:22 +0300
committerShai Berger <shai@platonix.com>2014-09-27 09:49:50 +0300
commitc1ae0621bab6b013025ec9024691ce7ad556409e (patch)
treedf1c2d71bae8fe23c00af16715fd3a9ebe332860
parentdbdae3a75512bddbf0b75ea6354fb3fc4bdb53cf (diff)
Fixed #22738 -- made finer distinctions for when Boolean is not detected on Oracle
Thanks Claude Paroz for partial fix and Simon Charrette for review
-rw-r--r--django/db/backends/__init__.py20
-rw-r--r--django/db/backends/mysql/base.py4
-rw-r--r--django/db/backends/oracle/base.py15
-rw-r--r--tests/inspectdb/tests.py21
-rw-r--r--tests/schema/tests.py2
5 files changed, 40 insertions, 22 deletions
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 8bdf6eed3c..ce3ea04d98 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -614,9 +614,6 @@ class BaseDatabaseFeatures(object):
# Can the backend introspect an BinaryField, instead of an TextField?
can_introspect_binary_field = True
- # What is the type returned when the backend introspect a BooleanField?
- introspected_boolean_field_type = 'BooleanField'
-
# Can the backend introspect an DecimalField, instead of an FloatField?
can_introspect_decimal_field = True
@@ -715,6 +712,23 @@ class BaseDatabaseFeatures(object):
except NotImplementedError:
return False
+ def introspected_boolean_field_type(self, field=None, created_separately=False):
+ """
+ What is the type returned when the backend introspects a BooleanField?
+ The optional arguments may be used to give further details of the field to be
+ introspected; in particular, they are provided by Django's test suite:
+ field -- the field definition
+ created_separately -- True if the field was added via a SchemaEditor's AddField,
+ False if the field was created with the model
+
+ Note that return value from this function is compared by tests against actual
+ introspection results; it should provide expectations, not run an introspection
+ itself.
+ """
+ if self.can_introspect_null and field and field.null:
+ return 'NullBooleanField'
+ return 'BooleanField'
+
class BaseDatabaseOperations(object):
"""
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index 0bd9c16e56..d2ba75f664 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -178,7 +178,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_regex_backreferencing = False
supports_date_lookup_using_string = False
can_introspect_binary_field = False
- introspected_boolean_field_type = 'IntegerField'
can_introspect_small_integer_field = True
supports_timezones = False
requires_explicit_null_ordering_when_grouping = True
@@ -225,6 +224,9 @@ class DatabaseFeatures(BaseDatabaseFeatures):
cursor.execute("SELECT 1 FROM mysql.time_zone LIMIT 1")
return cursor.fetchone() is not None
+ def introspected_boolean_field_type(self, *args):
+ return 'IntegerField'
+
class DatabaseOperations(BaseDatabaseOperations):
compiler_module = "django.db.backends.mysql.compiler"
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index c9a59d3970..b41386d4f0 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -125,19 +125,20 @@ class DatabaseFeatures(BaseDatabaseFeatures):
# select for update with limit can be achieved on Oracle, but not with the current backend.
supports_select_for_update_with_limit = False
- @cached_property
- def introspected_boolean_field_type(self):
+ def introspected_boolean_field_type(self, field=None, created_separately=False):
"""
Some versions of Oracle -- we've seen this on 11.2.0.1 and suspect
it goes back -- have a weird bug where, when an integer column is
- defined with a default, its precision is later reported on introspection
- as 0, regardless of the real precision. For Django introspection, this
- means that such columns are reported as IntegerField even if they are
- really BigIntegerField or BooleanField.
+ added to an existing table with a default, its precision is later
+ reported on introspection as 0, regardless of the real precision.
+ For Django introspection, this means that such columns are reported
+ as IntegerField even if they are really BigIntegerField or BooleanField.
The bug is solved in Oracle 11.2.0.2 and up.
"""
- return 'IntegerField' if self.connection.oracle_full_version < '11.2.0.2' else 'BooleanField'
+ if self.connection.oracle_full_version < '11.2.0.2' and field and field.has_default() and created_separately:
+ return 'IntegerField'
+ return super(DatabaseFeatures, self).introspected_boolean_field_type(field, created_separately)
class DatabaseOperations(BaseDatabaseOperations):
diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py
index 8b187191ae..708bae4fb8 100644
--- a/tests/inspectdb/tests.py
+++ b/tests/inspectdb/tests.py
@@ -9,6 +9,8 @@ from django.db import connection
from django.test import TestCase, skipUnlessDBFeature
from django.utils.six import PY3, StringIO
+from .models import ColumnTypes
+
class InspectDBTestCase(TestCase):
@@ -87,19 +89,18 @@ class InspectDBTestCase(TestCase):
else:
assertFieldType('big_int_field', "models.IntegerField()")
- if connection.features.introspected_boolean_field_type == 'BooleanField':
- assertFieldType('bool_field', "models.BooleanField()")
- if connection.features.can_introspect_null:
- assertFieldType('null_bool_field', "models.NullBooleanField()")
- else:
- assertFieldType('null_bool_field', "models.BooleanField()")
+ bool_field = ColumnTypes._meta.get_field('bool_field')
+ bool_field_type = connection.features.introspected_boolean_field_type(bool_field)
+ assertFieldType('bool_field', "models.{}()".format(bool_field_type))
+ null_bool_field = ColumnTypes._meta.get_field('null_bool_field')
+ null_bool_field_type = connection.features.introspected_boolean_field_type(null_bool_field)
+ if 'BooleanField' in null_bool_field_type:
+ assertFieldType('null_bool_field', "models.{}()".format(null_bool_field_type))
else:
- field_type = connection.features.introspected_boolean_field_type
- assertFieldType('bool_field', "models.{}()".format(field_type))
if connection.features.can_introspect_null:
- assertFieldType('null_bool_field', "models.{}(blank=True, null=True)".format(field_type))
+ assertFieldType('null_bool_field', "models.{}(blank=True, null=True)".format(null_bool_field_type))
else:
- assertFieldType('null_bool_field', "models.{}()".format(field_type))
+ assertFieldType('null_bool_field', "models.{}()".format(null_bool_field_type))
if connection.features.can_introspect_decimal_field:
assertFieldType('decimal_field', "models.DecimalField(max_digits=6, decimal_places=1)")
diff --git a/tests/schema/tests.py b/tests/schema/tests.py
index 82377041dc..88290338a1 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -314,7 +314,7 @@ class SchemaTests(TransactionTestCase):
columns = self.column_classes(Author)
# BooleanField are stored as TINYINT(1) on MySQL.
field_type = columns['awesome'][0]
- self.assertEqual(field_type, connection.features.introspected_boolean_field_type)
+ self.assertEqual(field_type, connection.features.introspected_boolean_field_type(new_field, created_separately=True))
def test_add_field_default_transform(self):
"""