summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2014-12-29 11:41:16 -0500
committerTim Graham <timograham@gmail.com>2015-01-31 12:33:11 -0500
commit75303b01a9cc900eebf1f27ba0bc6508334242fc (patch)
tree2a5da4f8a8036b5f833caa776ecec20dd81774d4 /django
parent64a899dc815f1a070dc7a7c22276e8bb41e46ea6 (diff)
Fixed #24245 -- Added introspection for database defaults.
Needed for tests for migrations handling of database defaults.
Diffstat (limited to 'django')
-rw-r--r--django/db/backends/base/features.py3
-rw-r--r--django/db/backends/mysql/introspection.py11
-rw-r--r--django/db/backends/oracle/features.py1
-rw-r--r--django/db/backends/sqlite3/introspection.py32
4 files changed, 33 insertions, 14 deletions
diff --git a/django/db/backends/base/features.py b/django/db/backends/base/features.py
index 4b4d5c6d75..a7bc85e683 100644
--- a/django/db/backends/base/features.py
+++ b/django/db/backends/base/features.py
@@ -125,6 +125,9 @@ class BaseDatabaseFeatures(object):
# This is True for all core backends.
can_introspect_null = True
+ # Can the backend introspect the default value of a column?
+ can_introspect_default = True
+
# Confirm support for introspected foreign keys
# Every database can do this reliably, except MySQL,
# which can't do it for MyISAM tables
diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py
index dc78a00bfc..aa3c008d13 100644
--- a/django/db/backends/mysql/introspection.py
+++ b/django/db/backends/mysql/introspection.py
@@ -9,8 +9,8 @@ from django.utils.encoding import force_text
from MySQLdb.constants import FIELD_TYPE
-FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('extra',))
-
+FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('extra', 'default'))
+InfoLine = namedtuple('InfoLine', 'col_name data_type max_len num_prec num_scale extra column_default')
foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
@@ -61,9 +61,9 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
# not visible length (#5725)
# - precision and scale (for decimal fields) (#5014)
# - auto_increment is not available in cursor.description
- InfoLine = namedtuple('InfoLine', 'col_name data_type max_len num_prec num_scale extra')
cursor.execute("""
- SELECT column_name, data_type, character_maximum_length, numeric_precision, numeric_scale, extra
+ SELECT column_name, data_type, character_maximum_length, numeric_precision,
+ numeric_scale, extra, column_default
FROM information_schema.columns
WHERE table_name = %s AND table_schema = DATABASE()""", [table_name])
field_info = {line[0]: InfoLine(*line) for line in cursor.fetchall()}
@@ -80,7 +80,8 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
to_int(field_info[col_name].num_prec) or line[4],
to_int(field_info[col_name].num_scale) or line[5])
+ (line[6],)
- + (field_info[col_name].extra,)))
+ + (field_info[col_name].extra,)
+ + (field_info[col_name].column_default,)))
)
return fields
diff --git a/django/db/backends/oracle/features.py b/django/db/backends/oracle/features.py
index 93c0beaf1e..ffa5c6474c 100644
--- a/django/db/backends/oracle/features.py
+++ b/django/db/backends/oracle/features.py
@@ -28,6 +28,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
has_bulk_insert = True
supports_tablespaces = True
supports_sequence_reset = False
+ can_introspect_default = False # Pending implementation by an interested person.
can_introspect_max_length = False
can_introspect_time_field = False
atomic_transactions = False
diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py
index 13b658bd6a..a002b79933 100644
--- a/django/db/backends/sqlite3/introspection.py
+++ b/django/db/backends/sqlite3/introspection.py
@@ -1,4 +1,5 @@
import re
+from collections import namedtuple
from django.db.backends.base.introspection import (
BaseDatabaseIntrospection, FieldInfo, TableInfo,
@@ -6,6 +7,7 @@ from django.db.backends.base.introspection import (
field_size_re = re.compile(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$')
+FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('default',))
def get_field_size(name):
@@ -69,8 +71,18 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
def get_table_description(self, cursor, table_name):
"Returns a description of the table, with the DB-API cursor.description interface."
- return [FieldInfo(info['name'], info['type'], None, info['size'], None, None,
- info['null_ok']) for info in self._table_info(cursor, table_name)]
+ return [
+ FieldInfo(
+ info['name'],
+ info['type'],
+ None,
+ info['size'],
+ None,
+ None,
+ info['null_ok'],
+ info['default'],
+ ) for info in self._table_info(cursor, table_name)
+ ]
def column_name_converter(self, name):
"""
@@ -211,13 +223,15 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
def _table_info(self, cursor, name):
cursor.execute('PRAGMA table_info(%s)' % self.connection.ops.quote_name(name))
- # cid, name, type, notnull, dflt_value, pk
- return [{'name': field[1],
- 'type': field[2],
- 'size': get_field_size(field[2]),
- 'null_ok': not field[3],
- 'pk': field[5] # undocumented
- } for field in cursor.fetchall()]
+ # cid, name, type, notnull, default_value, pk
+ return [{
+ 'name': field[1],
+ 'type': field[2],
+ 'size': get_field_size(field[2]),
+ 'null_ok': not field[3],
+ 'default': field[4],
+ 'pk': field[5], # undocumented
+ } for field in cursor.fetchall()]
def get_constraints(self, cursor, table_name):
"""