Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #16737 -- Support non-ascii column names in inspectdb

Thanks moof at metamoof.net for the report.
  • Loading branch information...
commit 8c41bd93c2412ddeb9dbe8bd73e1d3c3427d171b 1 parent 2817a29
Claude Paroz authored April 01, 2013
9  django/db/backends/mysql/introspection.py
@@ -2,6 +2,7 @@
2 2
 from .base import FIELD_TYPE
3 3
 
4 4
 from django.db.backends import BaseDatabaseIntrospection, FieldInfo
  5
+from django.utils.encoding import force_text
5 6
 
6 7
 
7 8
 foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
@@ -55,9 +56,11 @@ def get_table_description(self, cursor, table_name):
55 56
         numeric_map = dict([(line[0], tuple([int(n) for n in line[1:]])) for line in cursor.fetchall()])
56 57
 
57 58
         cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
58  
-        return [FieldInfo(*(line[:3] + (length_map.get(line[0], line[3]),)
59  
-                                     + numeric_map.get(line[0], line[4:6])
60  
-                                     + (line[6],)))
  59
+        return [FieldInfo(*((force_text(line[0]),)
  60
+                            + line[1:3]
  61
+                            + (length_map.get(line[0], line[3]),)
  62
+                            + numeric_map.get(line[0], line[4:6])
  63
+                            + (line[6],)))
61 64
             for line in cursor.description]
62 65
 
63 66
     def _name_to_index(self, cursor, table_name):
3  django/db/backends/postgresql_psycopg2/introspection.py
... ...
@@ -1,6 +1,7 @@
1 1
 from __future__ import unicode_literals
2 2
 
3 3
 from django.db.backends import BaseDatabaseIntrospection, FieldInfo
  4
+from django.utils.encoding import force_text
4 5
 
5 6
 
6 7
 class DatabaseIntrospection(BaseDatabaseIntrospection):
@@ -46,7 +47,7 @@ def get_table_description(self, cursor, table_name):
46 47
             WHERE table_name = %s""", [table_name])
47 48
         null_map = dict(cursor.fetchall())
48 49
         cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
49  
-        return [FieldInfo(*(line[:6] + (null_map[line[0]]=='YES',)))
  50
+        return [FieldInfo(*((force_text(line[0]),) + line[1:6] + (null_map[force_text(line[0])]=='YES',)))
50 51
                 for line in cursor.description]
51 52
 
52 53
     def get_relations(self, cursor, table_name):
4  tests/inspectdb/models.py
... ...
@@ -1,3 +1,6 @@
  1
+# -*- encoding: utf-8 -*-
  2
+from __future__ import unicode_literals
  3
+
1 4
 from django.db import models
2 5
 
3 6
 
@@ -29,6 +32,7 @@ class SpecialColumnName(models.Model):
29 32
     field_field_2 = models.IntegerField(db_column='__field')
30 33
     # Other chars
31 34
     prc_x = models.IntegerField(db_column='prc(%) x')
  35
+    non_ascii = models.IntegerField(db_column='tamaño')
32 36
 
33 37
 class ColumnTypes(models.Model):
34 38
     id = models.AutoField(primary_key=True)
8  tests/inspectdb/tests.py
... ...
@@ -1,3 +1,4 @@
  1
+# -*- encoding: utf-8 -*-
1 2
 from __future__ import unicode_literals
2 3
 
3 4
 import re
@@ -6,7 +7,7 @@
6 7
 from django.db import connection
7 8
 from django.test import TestCase, skipUnlessDBFeature
8 9
 from django.utils.unittest import expectedFailure
9  
-from django.utils.six import StringIO
  10
+from django.utils.six import PY3, StringIO
10 11
 
11 12
 if connection.vendor == 'oracle':
12 13
     expectedFailureOnOracle = expectedFailure
@@ -146,6 +147,11 @@ def test_special_column_name_introspection(self):
146 147
         self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output)
147 148
         self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output)
148 149
         self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)
  150
+        if PY3:
  151
+            # Python 3 allows non-ascii identifiers
  152
+            self.assertIn("tamaño = models.IntegerField()", output)
  153
+        else:
  154
+            self.assertIn("tama_o = models.IntegerField(db_column='tama\\xf1o')", output)
149 155
 
150 156
     def test_managed_models(self):
151 157
         """Test that by default the command generates models with `Meta.managed = False` (#14305)"""

0 notes on commit 8c41bd9

Please sign in to comment.
Something went wrong with that request. Please try again.