Fixed #23028: Added unique_togther support to inspectdb.

This commit is contained in:
Damien Nozay 2014-07-14 13:42:05 -07:00 committed by Tim Graham
parent b8d255071e
commit 70c54a3694
5 changed files with 40 additions and 5 deletions

View File

@ -21,8 +21,8 @@ class Command(InspectDBCommand):
self.gis_tables[table_name] = [geo_col] self.gis_tables[table_name] = [geo_col]
return field_type, field_params, field_notes return field_type, field_params, field_notes
def get_meta(self, table_name): def get_meta(self, table_name, constraints):
meta_lines = super(Command, self).get_meta(table_name) meta_lines = super(Command, self).get_meta(table_name, constraints)
if table_name in self.gis_tables: if table_name in self.gis_tables:
# If the table is a geographic one, then we need make # If the table is a geographic one, then we need make
# GeoManager the default manager for the model. # GeoManager the default manager for the model.

View File

@ -65,6 +65,10 @@ class Command(BaseCommand):
indexes = connection.introspection.get_indexes(cursor, table_name) indexes = connection.introspection.get_indexes(cursor, table_name)
except NotImplementedError: except NotImplementedError:
indexes = {} 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 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)): 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. comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
@ -135,7 +139,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): for meta_line in self.get_meta(table_name, constraints):
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):
@ -232,13 +236,26 @@ class Command(BaseCommand):
return field_type, field_params, field_notes 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 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
to the given database table name. 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:", " class Meta:",
" managed = False", " managed = False",
" db_table = '%s'" % table_name] " db_table = '%s'" % table_name]
if unique_together:
tup = '(' + ', '.join(unique_together) + ',)'
meta += [" unique_together = %s" % tup]
return meta

View File

@ -179,6 +179,8 @@ Management Commands
* :djadmin:`runserver` now uses daemon threads for faster reloading. * :djadmin:`runserver` now uses daemon threads for faster reloading.
* :djadmin:`inspectdb` now outputs ``Meta.unique_together``.
Models Models
^^^^^^ ^^^^^^

View File

@ -70,3 +70,11 @@ class ColumnTypes(models.Model):
text_field = models.TextField() text_field = models.TextField()
time_field = models.TimeField() time_field = models.TimeField()
url_field = models.URLField() url_field = models.URLField()
class UniqueTogether(models.Model):
field1 = models.IntegerField()
field2 = models.CharField(max_length=10)
class Meta:
unique_together = ('field1', 'field2')

View File

@ -217,6 +217,14 @@ class InspectDBTestCase(TestCase):
self.longMessage = False self.longMessage = False
self.assertIn(" managed = False", output, msg='inspectdb should generate unmanaged models.') 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', @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")
def test_custom_fields(self): def test_custom_fields(self):