Просмотр исходного кода

Fixed #29870 -- Added DurationField introspection for Oracle and PostgreSQL.

Thanks Tim Graham for the review.
Mariusz Felisiak 6 лет назад
Родитель
Сommit
328f5627dd

+ 3 - 0
django/db/backends/base/features.py

@@ -129,6 +129,9 @@ class BaseDatabaseFeatures:
     # Can the backend introspect an DecimalField, instead of an FloatField?
     can_introspect_decimal_field = True
 
+    # Can the backend introspect a DurationField, instead of a BigIntegerField?
+    can_introspect_duration_field = True
+
     # Can the backend introspect an IPAddressField, instead of an CharField?
     can_introspect_ip_address_field = False
 

+ 1 - 0
django/db/backends/mysql/features.py

@@ -15,6 +15,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     supports_date_lookup_using_string = False
     can_introspect_autofield = True
     can_introspect_binary_field = False
+    can_introspect_duration_field = False
     can_introspect_small_integer_field = True
     can_introspect_positive_integer_field = True
     introspected_boolean_field_type = 'IntegerField'

+ 1 - 0
django/db/backends/oracle/introspection.py

@@ -18,6 +18,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
         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',

+ 1 - 0
django/db/backends/postgresql/introspection.py

@@ -22,6 +22,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
         1083: 'TimeField',
         1114: 'DateTimeField',
         1184: 'DateTimeField',
+        1186: 'DurationField',
         1266: 'TimeField',
         1700: 'DecimalField',
         2950: 'UUIDField',

+ 1 - 0
django/db/backends/sqlite3/features.py

@@ -15,6 +15,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
     supports_mixed_date_datetime_comparisons = False
     autocommits_when_autocommit_is_off = True
     can_introspect_decimal_field = False
+    can_introspect_duration_field = False
     can_introspect_positive_integer_field = True
     can_introspect_small_integer_field = True
     supports_transactions = True

+ 7 - 0
docs/releases/2.2.txt

@@ -182,6 +182,9 @@ Management Commands
 * :option:`inspectdb --include-views` now creates models for materialized views
   on PostgreSQL.
 
+* :djadmin:`inspectdb` now introspects :class:`~django.db.models.DurationField`
+  for Oracle and PostgreSQL.
+
 Migrations
 ~~~~~~~~~~
 
@@ -274,6 +277,10 @@ Database backend API
   constraints or uniqueness errors while inserting or set
   ``DatabaseFeatures.supports_ignore_conflicts`` to ``False``.
 
+* Third party database backends must implement introspection for
+  ``DurationField`` or set ``DatabaseFeatures.can_introspect_duration_field``
+  to ``False``.
+
 :mod:`django.contrib.gis`
 -------------------------
 

+ 1 - 0
tests/introspection/models.py

@@ -24,6 +24,7 @@ class Reporter(models.Model):
     facebook_user_id = models.BigIntegerField(null=True)
     raw_data = models.BinaryField(null=True)
     small_int = models.SmallIntegerField()
+    interval = models.DurationField()
 
     class Meta:
         unique_together = ('first_name', 'last_name')

+ 11 - 6
tests/introspection/tests.py

@@ -77,11 +77,16 @@ class IntrospectionTests(TransactionTestCase):
             desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table)
         self.assertEqual(
             [datatype(r[1], r) for r in desc],
-            ['AutoField' if connection.features.can_introspect_autofield else 'IntegerField',
-             'CharField', 'CharField', 'CharField',
-             'BigIntegerField' if connection.features.can_introspect_big_integer_field else 'IntegerField',
-             'BinaryField' if connection.features.can_introspect_binary_field else 'TextField',
-             'SmallIntegerField' if connection.features.can_introspect_small_integer_field else 'IntegerField']
+            [
+                'AutoField' if connection.features.can_introspect_autofield else 'IntegerField',
+                'CharField',
+                'CharField',
+                'CharField',
+                'BigIntegerField' if connection.features.can_introspect_big_integer_field else 'IntegerField',
+                'BinaryField' if connection.features.can_introspect_binary_field else 'TextField',
+                'SmallIntegerField' if connection.features.can_introspect_small_integer_field else 'IntegerField',
+                'DurationField' if connection.features.can_introspect_duration_field else 'BigIntegerField',
+            ]
         )
 
     def test_get_table_description_col_lengths(self):
@@ -98,7 +103,7 @@ class IntrospectionTests(TransactionTestCase):
         nullable_by_backend = connection.features.interprets_empty_strings_as_nulls
         self.assertEqual(
             [r[6] for r in desc],
-            [False, nullable_by_backend, nullable_by_backend, nullable_by_backend, True, True, False]
+            [False, nullable_by_backend, nullable_by_backend, nullable_by_backend, True, True, False, False]
         )
 
     @skipUnlessDBFeature('can_introspect_autofield')