Add operation that renames tables
This commit is contained in:
parent
73e30e9d3b
commit
6f667999e1
|
@ -362,9 +362,9 @@ class BaseDatabaseSchemaEditor(object):
|
|||
return self._alter_many_to_many(model, old_field, new_field, strict)
|
||||
elif old_type is None or new_type is None:
|
||||
raise ValueError("Cannot alter field %s into %s - they are not compatible types (probably means only one is an M2M with implicit through model)" % (
|
||||
old_field,
|
||||
new_field,
|
||||
))
|
||||
old_field,
|
||||
new_field,
|
||||
))
|
||||
# Has unique been removed?
|
||||
if old_field.unique and not new_field.unique:
|
||||
# Find the unique constraint for this field
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
from .models import CreateModel, DeleteModel
|
||||
from .models import CreateModel, DeleteModel, AlterModelTable
|
||||
from .fields import AddField, RemoveField
|
||||
|
|
|
@ -50,3 +50,31 @@ class DeleteModel(Operation):
|
|||
|
||||
def describe(self):
|
||||
return "Delete model %s" % (self.name, )
|
||||
|
||||
|
||||
class AlterModelTable(Operation):
|
||||
"""
|
||||
Renames a model's table
|
||||
"""
|
||||
|
||||
def __init__(self, name, table):
|
||||
self.name = name
|
||||
self.table = table
|
||||
|
||||
def state_forwards(self, app_label, state):
|
||||
state.models[app_label, self.name.lower()].options["db_table"] = self.table
|
||||
|
||||
def database_forwards(self, app_label, schema_editor, from_state, to_state):
|
||||
old_app_cache = from_state.render()
|
||||
new_app_cache = to_state.render()
|
||||
schema_editor.alter_db_table(
|
||||
new_app_cache.get_model(app_label, self.name),
|
||||
old_app_cache.get_model(app_label, self.name)._meta.db_table,
|
||||
new_app_cache.get_model(app_label, self.name)._meta.db_table,
|
||||
)
|
||||
|
||||
def database_backwards(self, app_label, schema_editor, from_state, to_state):
|
||||
return self.database_forwards(app_label, schema_editor, from_state, to_state)
|
||||
|
||||
def describe(self):
|
||||
return "Rename table for %s to %s" % (self.name, self.table)
|
||||
|
|
|
@ -12,6 +12,7 @@ class AutodetectorTests(TestCase):
|
|||
"""
|
||||
|
||||
author_empty = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True))])
|
||||
author_name = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=200))])
|
||||
other_pony = ModelState("otherapp", "Pony", [("id", models.AutoField(primary_key=True))])
|
||||
other_stable = ModelState("otherapp", "Stable", [("id", models.AutoField(primary_key=True))])
|
||||
third_thing = ModelState("thirdapp", "Thing", [("id", models.AutoField(primary_key=True))])
|
||||
|
@ -95,3 +96,37 @@ class AutodetectorTests(TestCase):
|
|||
action = migration.operations[0]
|
||||
self.assertEqual(action.__class__.__name__, "DeleteModel")
|
||||
self.assertEqual(action.name, "Author")
|
||||
|
||||
def test_add_field(self):
|
||||
"Tests autodetection of new fields"
|
||||
# Make state
|
||||
before = self.make_project_state([self.author_empty])
|
||||
after = self.make_project_state([self.author_name])
|
||||
autodetector = MigrationAutodetector(before, after)
|
||||
changes = autodetector.changes()
|
||||
# Right number of migrations?
|
||||
self.assertEqual(len(changes['testapp']), 1)
|
||||
# Right number of actions?
|
||||
migration = changes['testapp'][0]
|
||||
self.assertEqual(len(migration.operations), 1)
|
||||
# Right action?
|
||||
action = migration.operations[0]
|
||||
self.assertEqual(action.__class__.__name__, "AddField")
|
||||
self.assertEqual(action.name, "name")
|
||||
|
||||
def test_remove_field(self):
|
||||
"Tests autodetection of removed fields"
|
||||
# Make state
|
||||
before = self.make_project_state([self.author_name])
|
||||
after = self.make_project_state([self.author_empty])
|
||||
autodetector = MigrationAutodetector(before, after)
|
||||
changes = autodetector.changes()
|
||||
# Right number of migrations?
|
||||
self.assertEqual(len(changes['testapp']), 1)
|
||||
# Right number of actions?
|
||||
migration = changes['testapp'][0]
|
||||
self.assertEqual(len(migration.operations), 1)
|
||||
# Right action?
|
||||
action = migration.operations[0]
|
||||
self.assertEqual(action.__class__.__name__, "RemoveField")
|
||||
self.assertEqual(action.name, "name")
|
||||
|
|
|
@ -114,3 +114,46 @@ class OperationTests(TestCase):
|
|||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards("test_adfl", editor, new_state, project_state)
|
||||
self.assertColumnNotExists("test_adfl_pony", "height")
|
||||
|
||||
def test_remove_field(self):
|
||||
"""
|
||||
Tests the RemoveField operation.
|
||||
"""
|
||||
project_state = self.set_up_test_model("test_rmfl")
|
||||
# Test the state alteration
|
||||
operation = migrations.RemoveField("Pony", "pink")
|
||||
new_state = project_state.clone()
|
||||
operation.state_forwards("test_rmfl", new_state)
|
||||
self.assertEqual(len(new_state.models["test_rmfl", "pony"].fields), 1)
|
||||
# Test the database alteration
|
||||
self.assertColumnExists("test_rmfl_pony", "pink")
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards("test_rmfl", editor, project_state, new_state)
|
||||
self.assertColumnNotExists("test_rmfl_pony", "pink")
|
||||
# And test reversal
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards("test_rmfl", editor, new_state, project_state)
|
||||
self.assertColumnExists("test_rmfl_pony", "pink")
|
||||
|
||||
def test_alter_model_table(self):
|
||||
"""
|
||||
Tests the AlterModelTable operation.
|
||||
"""
|
||||
project_state = self.set_up_test_model("test_almota")
|
||||
# Test the state alteration
|
||||
operation = migrations.AlterModelTable("Pony", "test_almota_pony_2")
|
||||
new_state = project_state.clone()
|
||||
operation.state_forwards("test_almota", new_state)
|
||||
self.assertEqual(new_state.models["test_almota", "pony"].options["db_table"], "test_almota_pony_2")
|
||||
# Test the database alteration
|
||||
self.assertTableExists("test_almota_pony")
|
||||
self.assertTableNotExists("test_almota_pony_2")
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards("test_almota", editor, project_state, new_state)
|
||||
self.assertTableNotExists("test_almota_pony")
|
||||
self.assertTableExists("test_almota_pony_2")
|
||||
# And test reversal
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards("test_almota", editor, new_state, project_state)
|
||||
self.assertTableExists("test_almota_pony")
|
||||
self.assertTableNotExists("test_almota_pony_2")
|
||||
|
|
Loading…
Reference in New Issue