Commit 8c41bd93 authored by Claude Paroz's avatar Claude Paroz
Browse files

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

Thanks moof at metamoof.net for the report.
parent 2817a29d
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ import re
from .base import FIELD_TYPE

from django.db.backends import BaseDatabaseIntrospection, FieldInfo
from django.utils.encoding import force_text


foreign_key_re = re.compile(r"\sCONSTRAINT `[^`]*` FOREIGN KEY \(`([^`]*)`\) REFERENCES `([^`]*)` \(`([^`]*)`\)")
@@ -55,7 +56,9 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
        numeric_map = dict([(line[0], tuple([int(n) for n in line[1:]])) for line in cursor.fetchall()])

        cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
        return [FieldInfo(*(line[:3] + (length_map.get(line[0], line[3]),)
        return [FieldInfo(*((force_text(line[0]),)
                            + 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]
+2 −1
Original line number Diff line number Diff line
from __future__ import unicode_literals

from django.db.backends import BaseDatabaseIntrospection, FieldInfo
from django.utils.encoding import force_text


class DatabaseIntrospection(BaseDatabaseIntrospection):
@@ -46,7 +47,7 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
            WHERE table_name = %s""", [table_name])
        null_map = dict(cursor.fetchall())
        cursor.execute("SELECT * FROM %s LIMIT 1" % self.connection.ops.quote_name(table_name))
        return [FieldInfo(*(line[:6] + (null_map[line[0]]=='YES',)))
        return [FieldInfo(*((force_text(line[0]),) + line[1:6] + (null_map[force_text(line[0])]=='YES',)))
                for line in cursor.description]

    def get_relations(self, cursor, table_name):
+4 −0
Original line number Diff line number Diff line
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals

from django.db import models


@@ -29,6 +32,7 @@ class SpecialColumnName(models.Model):
    field_field_2 = models.IntegerField(db_column='__field')
    # Other chars
    prc_x = models.IntegerField(db_column='prc(%) x')
    non_ascii = models.IntegerField(db_column='tamaño')

class ColumnTypes(models.Model):
    id = models.AutoField(primary_key=True)
+7 −1
Original line number Diff line number Diff line
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals

import re
@@ -6,7 +7,7 @@ from django.core.management import call_command
from django.db import connection
from django.test import TestCase, skipUnlessDBFeature
from django.utils.unittest import expectedFailure
from django.utils.six import StringIO
from django.utils.six import PY3, StringIO

if connection.vendor == 'oracle':
    expectedFailureOnOracle = expectedFailure
@@ -146,6 +147,11 @@ class InspectDBTestCase(TestCase):
        self.assertIn("field_field_0 = models.IntegerField(db_column='%s__')" % base_name, output)
        self.assertIn("field_field_1 = models.IntegerField(db_column='__field')", output)
        self.assertIn("prc_x = models.IntegerField(db_column='prc(%) x')", output)
        if PY3:
            # Python 3 allows non-ascii identifiers
            self.assertIn("tamaño = models.IntegerField()", output)
        else:
            self.assertIn("tama_o = models.IntegerField(db_column='tama\\xf1o')", output)

    def test_managed_models(self):
        """Test that by default the command generates models with `Meta.managed = False` (#14305)"""