Add operation that renames tables
This commit is contained in:
parent
73e30e9d3b
commit
6f667999e1
|
@ -1,2 +1,2 @@
|
||||||
from .models import CreateModel, DeleteModel
|
from .models import CreateModel, DeleteModel, AlterModelTable
|
||||||
from .fields import AddField, RemoveField
|
from .fields import AddField, RemoveField
|
||||||
|
|
|
@ -50,3 +50,31 @@ class DeleteModel(Operation):
|
||||||
|
|
||||||
def describe(self):
|
def describe(self):
|
||||||
return "Delete model %s" % (self.name, )
|
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_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_pony = ModelState("otherapp", "Pony", [("id", models.AutoField(primary_key=True))])
|
||||||
other_stable = ModelState("otherapp", "Stable", [("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))])
|
third_thing = ModelState("thirdapp", "Thing", [("id", models.AutoField(primary_key=True))])
|
||||||
|
@ -95,3 +96,37 @@ class AutodetectorTests(TestCase):
|
||||||
action = migration.operations[0]
|
action = migration.operations[0]
|
||||||
self.assertEqual(action.__class__.__name__, "DeleteModel")
|
self.assertEqual(action.__class__.__name__, "DeleteModel")
|
||||||
self.assertEqual(action.name, "Author")
|
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:
|
with connection.schema_editor() as editor:
|
||||||
operation.database_backwards("test_adfl", editor, new_state, project_state)
|
operation.database_backwards("test_adfl", editor, new_state, project_state)
|
||||||
self.assertColumnNotExists("test_adfl_pony", "height")
|
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