Loading django/db/backends/mysql/base.py +1 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): supports_binary_field = six.PY2 supports_regex_backreferencing = False supports_date_lookup_using_string = False can_introspect_autofield = True can_introspect_binary_field = False can_introspect_small_integer_field = True supports_timezones = False Loading django/db/backends/mysql/introspection.py +31 −18 Original line number Diff line number Diff line from collections import namedtuple import re from .base import FIELD_TYPE from django.utils.datastructures import OrderedSet from django.db.backends import BaseDatabaseIntrospection, FieldInfo, TableInfo from django.utils.encoding import force_text FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('extra',)) foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") Loading Loading @@ -32,6 +34,12 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): FIELD_TYPE.VAR_STRING: 'CharField', } def get_field_type(self, data_type, description): field_type = super(DatabaseIntrospection, self).get_field_type(data_type, description) if field_type == 'IntegerField' and 'auto_increment' in description.extra: return 'AutoField' return field_type def get_table_list(self, cursor): """ Returns a list of table and view names in the current database. Loading @@ -44,28 +52,33 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): """ Returns a description of the table, with the DB-API cursor.description interface." """ # varchar length returned by cursor.description is an internal length, # not visible length (#5725), use information_schema database to fix this cursor.execute(""" SELECT column_name, character_maximum_length FROM information_schema.columns WHERE table_name = %s AND table_schema = DATABASE() AND character_maximum_length IS NOT NULL""", [table_name]) length_map = dict(cursor.fetchall()) # Also getting precision and scale from information_schema (see #5014) # information_schema database gives more accurate results for some figures: # - varchar length returned by cursor.description is an internal length, # 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, numeric_precision, numeric_scale FROM information_schema.columns WHERE table_name = %s AND table_schema = DATABASE() AND data_type='decimal'""", [table_name]) numeric_map = dict((line[0], tuple(int(n) for n in line[1:])) for line in cursor.fetchall()) SELECT column_name, data_type, character_maximum_length, numeric_precision, numeric_scale, extra FROM information_schema.columns WHERE table_name = %s AND table_schema = DATABASE()""", [table_name]) field_info = dict((line[0], InfoLine(*line)) for line in cursor.fetchall()) cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name)) return [FieldInfo(*((force_text(line[0]),) to_int = lambda i: int(i) if i is not None else i fields = [] for line in cursor.description: col_name = force_text(line[0]) fields.append( FieldInfo(*((col_name,) + line[1:3] + (length_map.get(line[0], line[3]),) + numeric_map.get(line[0], line[4:6]) + (line[6],))) for line in cursor.description] + (to_int(field_info[col_name].max_len) or line[3], 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,))) ) return fields def _name_to_index(self, cursor, table_name): """ Loading Loading
django/db/backends/mysql/base.py +1 −0 Original line number Diff line number Diff line Loading @@ -173,6 +173,7 @@ class DatabaseFeatures(BaseDatabaseFeatures): supports_binary_field = six.PY2 supports_regex_backreferencing = False supports_date_lookup_using_string = False can_introspect_autofield = True can_introspect_binary_field = False can_introspect_small_integer_field = True supports_timezones = False Loading
django/db/backends/mysql/introspection.py +31 −18 Original line number Diff line number Diff line from collections import namedtuple import re from .base import FIELD_TYPE from django.utils.datastructures import OrderedSet from django.db.backends import BaseDatabaseIntrospection, FieldInfo, TableInfo from django.utils.encoding import force_text FieldInfo = namedtuple('FieldInfo', FieldInfo._fields + ('extra',)) foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)") Loading Loading @@ -32,6 +34,12 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): FIELD_TYPE.VAR_STRING: 'CharField', } def get_field_type(self, data_type, description): field_type = super(DatabaseIntrospection, self).get_field_type(data_type, description) if field_type == 'IntegerField' and 'auto_increment' in description.extra: return 'AutoField' return field_type def get_table_list(self, cursor): """ Returns a list of table and view names in the current database. Loading @@ -44,28 +52,33 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): """ Returns a description of the table, with the DB-API cursor.description interface." """ # varchar length returned by cursor.description is an internal length, # not visible length (#5725), use information_schema database to fix this cursor.execute(""" SELECT column_name, character_maximum_length FROM information_schema.columns WHERE table_name = %s AND table_schema = DATABASE() AND character_maximum_length IS NOT NULL""", [table_name]) length_map = dict(cursor.fetchall()) # Also getting precision and scale from information_schema (see #5014) # information_schema database gives more accurate results for some figures: # - varchar length returned by cursor.description is an internal length, # 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, numeric_precision, numeric_scale FROM information_schema.columns WHERE table_name = %s AND table_schema = DATABASE() AND data_type='decimal'""", [table_name]) numeric_map = dict((line[0], tuple(int(n) for n in line[1:])) for line in cursor.fetchall()) SELECT column_name, data_type, character_maximum_length, numeric_precision, numeric_scale, extra FROM information_schema.columns WHERE table_name = %s AND table_schema = DATABASE()""", [table_name]) field_info = dict((line[0], InfoLine(*line)) for line in cursor.fetchall()) cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name)) return [FieldInfo(*((force_text(line[0]),) to_int = lambda i: int(i) if i is not None else i fields = [] for line in cursor.description: col_name = force_text(line[0]) fields.append( FieldInfo(*((col_name,) + line[1:3] + (length_map.get(line[0], line[3]),) + numeric_map.get(line[0], line[4:6]) + (line[6],))) for line in cursor.description] + (to_int(field_info[col_name].max_len) or line[3], 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,))) ) return fields def _name_to_index(self, cursor, table_name): """ Loading