diff --git a/django/db/backends/mysql/introspection.py b/django/db/backends/mysql/introspection.py index 041fbee1b24..3b5a6fecd3e 100644 --- a/django/db/backends/mysql/introspection.py +++ b/django/db/backends/mysql/introspection.py @@ -36,9 +36,20 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): return [row[0] for row in cursor.fetchall()] def get_table_description(self, cursor, table_name): - "Returns a description of the table, with the DB-API cursor.description interface." + """ + 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()) + cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name)) - return cursor.description + return [line[:3] + (length_map.get(line[0], line[3]),) + line[4:] + for line in cursor.description] def _name_to_index(self, cursor, table_name): """ diff --git a/tests/regressiontests/introspection/tests.py b/tests/regressiontests/introspection/tests.py index e7cf7b9e1ad..a54e0c670b4 100644 --- a/tests/regressiontests/introspection/tests.py +++ b/tests/regressiontests/introspection/tests.py @@ -89,6 +89,11 @@ class IntrospectionTests(six.with_metaclass(IgnoreNotimplementedError, TestCase) [datatype(r[1], r) for r in desc], ['IntegerField', 'CharField', 'CharField', 'CharField', 'BigIntegerField'] ) + # Check also length of CharFields + self.assertEqual( + [r[3] for r in desc if datatype(r[1], r) == 'CharField'], + [30, 30, 75] + ) # Oracle forces null=True under the hood in some cases (see # https://docs.djangoproject.com/en/dev/ref/databases/#null-and-empty-strings)