diff --git a/django/core/management.py b/django/core/management.py index 050aad88e8..376d59118d 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -563,7 +563,7 @@ def get_sql_evolution_check_for_new_fields(klass, new_table_name): db_table = new_table_name for f in opts.fields: existing_fields = introspection.get_columns(cursor,db_table) - if f.column not in existing_fields and f.aka and f.aka not in existing_fields and len(set(f.aka) & set(existing_fields))==0: + if f.column not in existing_fields and (not f.aka or f.aka not in existing_fields and len(set(f.aka) & set(existing_fields))==0): rel_field = f data_type = f.get_internal_type() col_type = data_types[data_type] @@ -702,7 +702,7 @@ def get_sql_evolution_check_for_dead_fields(klass, new_table_name): if len(suspect_fields)>0: output.append( '-- warning: as the following may cause data loss, it/they must be run manually' ) for suspect_field in suspect_fields: - output.append( backend.get_drop_column_sql( db_table, suspect_field ) ) + output.append( '-- '+ backend.get_drop_column_sql( db_table, suspect_field ) ) output.append( '-- end warning' ) return output diff --git a/django/db/backends/mysql/base.py b/django/db/backends/mysql/base.py index 908a08f239..7f5fa8d00e 100644 --- a/django/db/backends/mysql/base.py +++ b/django/db/backends/mysql/base.py @@ -280,7 +280,7 @@ def get_add_column_sql( table_name, col_name, col_type, null, unique, primary_ke def get_drop_column_sql( table_name, col_name ): output = [] - output.append( '-- ALTER TABLE '+ quote_name(table_name) +' DROP COLUMN '+ quote_name(col_name) + ';' ) + output.append( 'ALTER TABLE '+ quote_name(table_name) +' DROP COLUMN '+ quote_name(col_name) + ';' ) return '\n'.join(output) diff --git a/django/db/backends/postgresql/base.py b/django/db/backends/postgresql/base.py index 82a0501de8..3dd54726ea 100644 --- a/django/db/backends/postgresql/base.py +++ b/django/db/backends/postgresql/base.py @@ -315,7 +315,7 @@ def get_add_column_sql( table_name, col_name, col_type, null, unique, primary_ke def get_drop_column_sql( table_name, col_name ): output = [] - output.append( '-- ALTER TABLE '+ quote_name(table_name) +' DROP COLUMN '+ quote_name(col_name) + ';' ) + output.append( 'ALTER TABLE '+ quote_name(table_name) +' DROP COLUMN '+ quote_name(col_name) + ';' ) return '\n'.join(output) # Register these custom typecasts, because Django expects dates/times to be diff --git a/tests/modeltests/schema_evolution/__init__.py b/tests/modeltests/schema_evolution/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/modeltests/schema_evolution/models.py b/tests/modeltests/schema_evolution/models.py new file mode 100644 index 0000000000..7842e6209a --- /dev/null +++ b/tests/modeltests/schema_evolution/models.py @@ -0,0 +1,91 @@ +""" +Schema Evolution Tests +""" + +from django.db import models + +GENDER_CHOICES = ( + ('M', 'Male'), + ('F', 'Female'), +) + +class Person(models.Model): + name = models.CharField(maxlength=20) + gender = models.CharField(maxlength=1, choices=GENDER_CHOICES) + gender2 = models.CharField(maxlength=1, choices=GENDER_CHOICES, aka='gender_old') + + def __unicode__(self): + return self.name + + class Meta: + aka = ('PersonOld', 'OtherBadName') + +__test__ = {'API_TESTS':""" +>>> import django +>>> from django.core import management +>>> from django.db import backend, models +>>> from django.db import connection, get_introspection_module +>>> app = models.get_apps()[-1] +>>> cursor = connection.cursor() + +# the table as it is supposed to be +>>> create_table_sql = management.get_sql_all(app) +>>> print create_table_sql +['CREATE TABLE `schema_evolution_person` (\\n `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,\\n `name` varchar(20) NOT NULL,\\n `gender` varchar(1) NOT NULL,\\n `gender2` varchar(1) NOT NULL\\n)\\n;'] + +# make sure we don't evolve an unedited table +>>> management.get_sql_evolution(app) +[] + +# delete a column, so it looks like we've recently added a field +>>> sql = backend.get_drop_column_sql( 'schema_evolution_person', 'gender' ) +>>> print sql +ALTER TABLE `schema_evolution_person` DROP COLUMN `gender`; +>>> cursor.execute(sql) +0L +>>> management.get_sql_evolution(app) +['ALTER TABLE `schema_evolution_person` ADD COLUMN `gender` varchar(1) NOT NULL;'] + +# reset the db +>>> cursor.execute('DROP TABLE schema_evolution_person;'); cursor.execute(create_table_sql[0]) +0L\n0L + +# add a column, so it looks like we've recently deleted a field +>>> cursor.execute('ALTER TABLE `schema_evolution_person` ADD COLUMN `gender_nothere` varchar(1) NOT NULL;') +0L +>>> management.get_sql_evolution(app) +['-- warning: as the following may cause data loss, it/they must be run manually', u'-- ALTER TABLE `schema_evolution_person` DROP COLUMN `gender_nothere`;', '-- end warning'] + +# reset the db +>>> cursor.execute('DROP TABLE schema_evolution_person;'); cursor.execute(create_table_sql[0]) +0L\n0L + +# rename column, so it looks like we've recently renamed a field +>>> cursor.execute('ALTER TABLE `schema_evolution_person` CHANGE COLUMN `gender2` `gender_old` varchar(1) NOT NULL;') +0L +>>> management.get_sql_evolution(app) +['ALTER TABLE `schema_evolution_person` CHANGE COLUMN `gender_old` `gender2` varchar(1) NOT NULL;'] + +# reset the db +>>> cursor.execute('DROP TABLE schema_evolution_person;'); cursor.execute(create_table_sql[0]) +0L\n0L + +# rename table, so it looks like we've recently renamed a model +>>> cursor.execute('ALTER TABLE `schema_evolution_person` RENAME TO `schema_evolution_personold`') +0L +>>> management.get_sql_evolution(app) +['ALTER TABLE `schema_evolution_personold` RENAME TO `schema_evolution_person`;'] + +# reset the db +>>> cursor.execute(create_table_sql[0]) +0L + +# change column flags, so it looks like we've recently changed a column flag +>>> cursor.execute('ALTER TABLE `schema_evolution_person` MODIFY COLUMN `name` varchar(10) NULL;') +0L +>>> management.get_sql_evolution(app) +['ALTER TABLE `schema_evolution_person` MODIFY COLUMN `name` varchar(20) NOT NULL;'] + + +"""} +