From 70c54a3694975c43a2e0e22c4a90c3cbe1eb54e4 Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Mon, 14 Jul 2014 13:42:05 -0700 Subject: [PATCH] Fixed #23028: Added unique_togther support to inspectdb. --- .../gis/management/commands/inspectdb.py | 4 ++-- django/core/management/commands/inspectdb.py | 23 ++++++++++++++++--- docs/releases/1.8.txt | 2 ++ tests/inspectdb/models.py | 8 +++++++ tests/inspectdb/tests.py | 8 +++++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/django/contrib/gis/management/commands/inspectdb.py b/django/contrib/gis/management/commands/inspectdb.py index 679fe84ca3..502f816ea4 100644 --- a/django/contrib/gis/management/commands/inspectdb.py +++ b/django/contrib/gis/management/commands/inspectdb.py @@ -21,8 +21,8 @@ class Command(InspectDBCommand): self.gis_tables[table_name] = [geo_col] return field_type, field_params, field_notes - def get_meta(self, table_name): - meta_lines = super(Command, self).get_meta(table_name) + def get_meta(self, table_name, constraints): + meta_lines = super(Command, self).get_meta(table_name, constraints) if table_name in self.gis_tables: # If the table is a geographic one, then we need make # GeoManager the default manager for the model. diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py index 91aa3255d7..83ba5bf8dc 100644 --- a/django/core/management/commands/inspectdb.py +++ b/django/core/management/commands/inspectdb.py @@ -65,6 +65,10 @@ class Command(BaseCommand): indexes = connection.introspection.get_indexes(cursor, table_name) except NotImplementedError: indexes = {} + try: + constraints = connection.introspection.get_constraints(cursor, table_name) + except NotImplementedError: + constraints = {} used_column_names = [] # Holds column names used in the table so far for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)): comment_notes = [] # Holds Field notes, to be displayed in a Python comment. @@ -135,7 +139,7 @@ class Command(BaseCommand): if comment_notes: field_desc += ' # ' + ' '.join(comment_notes) yield ' %s' % field_desc - for meta_line in self.get_meta(table_name): + for meta_line in self.get_meta(table_name, constraints): yield meta_line def normalize_col_name(self, col_name, used_column_names, is_relation): @@ -232,13 +236,26 @@ class Command(BaseCommand): return field_type, field_params, field_notes - def get_meta(self, table_name): + def get_meta(self, table_name, constraints): """ Return a sequence comprising the lines of code necessary to construct the inner Meta class for the model corresponding to the given database table name. """ - return ["", + unique_together = [] + for index, params in constraints.items(): + if params['unique']: + columns = params['columns'] + if len(columns) > 1: + # we do not want to include the u"" or u'' prefix + # so we build the string rather than interpolate the tuple + tup = '(' + ', '.join("'%s'" % c for c in columns) + ')' + unique_together.append(tup) + meta = ["", " class Meta:", " managed = False", " db_table = '%s'" % table_name] + if unique_together: + tup = '(' + ', '.join(unique_together) + ',)' + meta += [" unique_together = %s" % tup] + return meta diff --git a/docs/releases/1.8.txt b/docs/releases/1.8.txt index 78ade8f92f..690480a4e1 100644 --- a/docs/releases/1.8.txt +++ b/docs/releases/1.8.txt @@ -179,6 +179,8 @@ Management Commands * :djadmin:`runserver` now uses daemon threads for faster reloading. +* :djadmin:`inspectdb` now outputs ``Meta.unique_together``. + Models ^^^^^^ diff --git a/tests/inspectdb/models.py b/tests/inspectdb/models.py index 6b55ca7881..d55b457abe 100644 --- a/tests/inspectdb/models.py +++ b/tests/inspectdb/models.py @@ -70,3 +70,11 @@ class ColumnTypes(models.Model): text_field = models.TextField() time_field = models.TimeField() url_field = models.URLField() + + +class UniqueTogether(models.Model): + field1 = models.IntegerField() + field2 = models.CharField(max_length=10) + + class Meta: + unique_together = ('field1', 'field2') diff --git a/tests/inspectdb/tests.py b/tests/inspectdb/tests.py index 2fa4e25453..fb72b3756f 100644 --- a/tests/inspectdb/tests.py +++ b/tests/inspectdb/tests.py @@ -217,6 +217,14 @@ class InspectDBTestCase(TestCase): self.longMessage = False self.assertIn(" managed = False", output, msg='inspectdb should generate unmanaged models.') + def test_unique_together_meta(self): + out = StringIO() + call_command('inspectdb', + table_name_filter=lambda tn: tn.startswith('inspectdb_uniquetogether'), + stdout=out) + output = out.getvalue() + self.assertIn(" unique_together = (('field1', 'field2'),)", output, msg='inspectdb should generate unique_together.') + @skipUnless(connection.vendor == 'sqlite', "Only patched sqlite's DatabaseIntrospection.data_types_reverse for this test") def test_custom_fields(self):