mirror of
https://github.com/django/django.git
synced 2025-01-09 01:46:20 +00:00
Fixed #25274 --- Made inspectdb handle renamed fields in unique_together.
This commit is contained in:
parent
ec202eff84
commit
2cb50f935a
@ -71,6 +71,7 @@ class Command(BaseCommand):
|
|||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
constraints = {}
|
constraints = {}
|
||||||
used_column_names = [] # Holds column names used in the table so far
|
used_column_names = [] # Holds column names used in the table so far
|
||||||
|
column_to_field_name = {} # Maps column names to names of model fields
|
||||||
for row in connection.introspection.get_table_description(cursor, table_name):
|
for row in connection.introspection.get_table_description(cursor, table_name):
|
||||||
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
|
comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
|
||||||
extra_params = OrderedDict() # Holds Field parameters such as 'db_column'.
|
extra_params = OrderedDict() # Holds Field parameters such as 'db_column'.
|
||||||
@ -83,6 +84,7 @@ class Command(BaseCommand):
|
|||||||
comment_notes.extend(notes)
|
comment_notes.extend(notes)
|
||||||
|
|
||||||
used_column_names.append(att_name)
|
used_column_names.append(att_name)
|
||||||
|
column_to_field_name[column_name] = att_name
|
||||||
|
|
||||||
# Add primary_key and unique, if necessary.
|
# Add primary_key and unique, if necessary.
|
||||||
if column_name in indexes:
|
if column_name in indexes:
|
||||||
@ -145,7 +147,7 @@ class Command(BaseCommand):
|
|||||||
if comment_notes:
|
if comment_notes:
|
||||||
field_desc += ' # ' + ' '.join(comment_notes)
|
field_desc += ' # ' + ' '.join(comment_notes)
|
||||||
yield ' %s' % field_desc
|
yield ' %s' % field_desc
|
||||||
for meta_line in self.get_meta(table_name, constraints):
|
for meta_line in self.get_meta(table_name, constraints, column_to_field_name):
|
||||||
yield meta_line
|
yield meta_line
|
||||||
|
|
||||||
def normalize_col_name(self, col_name, used_column_names, is_relation):
|
def normalize_col_name(self, col_name, used_column_names, is_relation):
|
||||||
@ -242,7 +244,7 @@ class Command(BaseCommand):
|
|||||||
|
|
||||||
return field_type, field_params, field_notes
|
return field_type, field_params, field_notes
|
||||||
|
|
||||||
def get_meta(self, table_name, constraints):
|
def get_meta(self, table_name, constraints, column_to_field_name):
|
||||||
"""
|
"""
|
||||||
Return a sequence comprising the lines of code necessary
|
Return a sequence comprising the lines of code necessary
|
||||||
to construct the inner Meta class for the model corresponding
|
to construct the inner Meta class for the model corresponding
|
||||||
@ -255,7 +257,7 @@ class Command(BaseCommand):
|
|||||||
if len(columns) > 1:
|
if len(columns) > 1:
|
||||||
# we do not want to include the u"" or u'' prefix
|
# we do not want to include the u"" or u'' prefix
|
||||||
# so we build the string rather than interpolate the tuple
|
# so we build the string rather than interpolate the tuple
|
||||||
tup = '(' + ', '.join("'%s'" % c for c in columns) + ')'
|
tup = '(' + ', '.join("'%s'" % column_to_field_name[c] for c in columns) + ')'
|
||||||
unique_together.append(tup)
|
unique_together.append(tup)
|
||||||
meta = ["",
|
meta = ["",
|
||||||
" class Meta:",
|
" class Meta:",
|
||||||
|
@ -9,4 +9,5 @@ Django 1.8.8 fixes several bugs in 1.8.7.
|
|||||||
Bugfixes
|
Bugfixes
|
||||||
========
|
========
|
||||||
|
|
||||||
* ...
|
* Fixed incorrect ``unique_together`` field name generation by ``inspectdb``
|
||||||
|
(:ticket:`25274`).
|
||||||
|
@ -72,6 +72,13 @@ class ColumnTypes(models.Model):
|
|||||||
class UniqueTogether(models.Model):
|
class UniqueTogether(models.Model):
|
||||||
field1 = models.IntegerField()
|
field1 = models.IntegerField()
|
||||||
field2 = models.CharField(max_length=10)
|
field2 = models.CharField(max_length=10)
|
||||||
|
from_field = models.IntegerField(db_column='from')
|
||||||
|
non_unique = models.IntegerField(db_column='non__unique_column')
|
||||||
|
non_unique_0 = models.IntegerField(db_column='non_unique__column')
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
unique_together = ('field1', 'field2')
|
unique_together = [
|
||||||
|
('field1', 'field2'),
|
||||||
|
('from_field', 'field1'),
|
||||||
|
('non_unique', 'non_unique_0'),
|
||||||
|
]
|
||||||
|
@ -234,10 +234,18 @@ class InspectDBTestCase(TestCase):
|
|||||||
table_name_filter=lambda tn: tn.startswith('inspectdb_uniquetogether'),
|
table_name_filter=lambda tn: tn.startswith('inspectdb_uniquetogether'),
|
||||||
stdout=out)
|
stdout=out)
|
||||||
output = out.getvalue()
|
output = out.getvalue()
|
||||||
self.assertIn(
|
unique_re = re.compile(r'.*unique_together = \((.+),\).*')
|
||||||
" unique_together = (('field1', 'field2'),)", output,
|
unique_together_match = re.findall(unique_re, output)
|
||||||
msg='inspectdb should generate unique_together.'
|
# There should be one unique_together tuple.
|
||||||
)
|
self.assertEqual(len(unique_together_match), 1)
|
||||||
|
fields = unique_together_match[0]
|
||||||
|
# Fields with db_column = field name.
|
||||||
|
self.assertIn("('field1', 'field2')", fields)
|
||||||
|
# Fields from columns whose names are Python keywords.
|
||||||
|
self.assertIn("('field1', 'field2')", fields)
|
||||||
|
# Fields whose names normalize to the same Python field name and hence
|
||||||
|
# are given an integer suffix.
|
||||||
|
self.assertIn("('non_unique_column', 'non_unique_column_0')", fields)
|
||||||
|
|
||||||
@skipUnless(connection.vendor == 'sqlite',
|
@skipUnless(connection.vendor == 'sqlite',
|
||||||
"Only patched sqlite's DatabaseIntrospection.data_types_reverse for this test")
|
"Only patched sqlite's DatabaseIntrospection.data_types_reverse for this test")
|
||||||
|
Loading…
Reference in New Issue
Block a user