summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaude Paroz <claude@2xlibre.net>2014-09-26 08:43:50 +0200
committerClaude Paroz <claude@2xlibre.net>2014-09-26 20:03:44 +0200
commitdbdae3a75512bddbf0b75ea6354fb3fc4bdb53cf (patch)
tree0549f86a215a0a04703ed47ee8ec082d87f34cda
parent45840927d3516770be2654422e752357d5c063a5 (diff)
Fixed #22738 -- Abstracted boolean field type introspection
Thanks maxi for the report, Shai Berger for his help with the patch and Tim Graham for the review.
-rw-r--r--django/db/backends/__init__.py4
-rw-r--r--django/db/backends/mysql/base.py2
-rw-r--r--django/db/backends/oracle/base.py28
-rw-r--r--tests/inspectdb/tests.py9
-rw-r--r--tests/schema/tests.py11
5 files changed, 24 insertions, 30 deletions
diff --git a/django/db/backends/__init__.py b/django/db/backends/__init__.py
index 9873d9cba6..8bdf6eed3c 100644
--- a/django/db/backends/__init__.py
+++ b/django/db/backends/__init__.py
@@ -614,8 +614,8 @@ class BaseDatabaseFeatures(object):
# Can the backend introspect an BinaryField, instead of an TextField?
can_introspect_binary_field = True
- # Can the backend introspect an BooleanField, instead of an IntegerField?
- can_introspect_boolean_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
diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py
index 7223780081..0bd9c16e56 100644
--- a/django/db/backends/mysql/base.py
+++ b/django/db/backends/mysql/base.py
@@ -178,7 +178,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_regex_backreferencing = False
supports_date_lookup_using_string = False
can_introspect_binary_field = False
- can_introspect_boolean_field = False
+ introspected_boolean_field_type = 'IntegerField'
can_introspect_small_integer_field = True
supports_timezones = False
requires_explicit_null_ordering_when_grouping = True
diff --git a/django/db/backends/oracle/base.py b/django/db/backends/oracle/base.py
index 083ba18daa..c9a59d3970 100644
--- a/django/db/backends/oracle/base.py
+++ b/django/db/backends/oracle/base.py
@@ -125,6 +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):
+ """
+ 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.
+
+ 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'
+
class DatabaseOperations(BaseDatabaseOperations):
compiler_module = "django.db.backends.oracle.compiler"
@@ -735,20 +749,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
except ValueError:
return None
- @cached_property
- def version_has_default_introspection_bug(self):
- """
- 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.
-
- The bug is solved in Oracle 11.2.0.2 and up.
- """
- return self.oracle_full_version < '11.2.0.2'
-
class OracleParam(object):
"""
diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py
index fb72b3756f..8b187191ae 100644
--- a/tests/inspectdb/tests.py
+++ b/tests/inspectdb/tests.py
@@ -87,18 +87,19 @@ class InspectDBTestCase(TestCase):
else:
assertFieldType('big_int_field', "models.IntegerField()")
- if connection.features.can_introspect_boolean_field:
+ 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()")
else:
- assertFieldType('bool_field', "models.IntegerField()")
+ 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.IntegerField(blank=True, null=True)")
+ assertFieldType('null_bool_field', "models.{}(blank=True, null=True)".format(field_type))
else:
- assertFieldType('null_bool_field', "models.IntegerField()")
+ assertFieldType('null_bool_field', "models.{}()".format(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 02207ff6e9..82377041dc 100644
--- a/tests/schema/tests.py
+++ b/tests/schema/tests.py
@@ -313,15 +313,8 @@ class SchemaTests(TransactionTestCase):
# Ensure the field is right afterwards
columns = self.column_classes(Author)
# BooleanField are stored as TINYINT(1) on MySQL.
- field_type, field_info = columns['awesome']
- if connection.vendor == 'mysql':
- self.assertEqual(field_type, 'IntegerField')
- self.assertEqual(field_info.precision, 1)
- elif connection.vendor == 'oracle' and connection.version_has_default_introspection_bug:
- self.assertEqual(field_type, 'IntegerField')
- self.assertEqual(field_info.precision, 0)
- else:
- self.assertEqual(field_type, 'BooleanField')
+ field_type = columns['awesome'][0]
+ self.assertEqual(field_type, connection.features.introspected_boolean_field_type)
def test_add_field_default_transform(self):
"""