Add db_table and db_tablespace handling

This commit is contained in:
Andrew Godwin 2012-08-10 15:03:18 +01:00
parent 184cf9ab79
commit 60873ea2ad
2 changed files with 65 additions and 6 deletions

View File

@ -1,9 +1,3 @@
import sys
import time
from django.conf import settings
from django.db import transaction
from django.db.utils import load_backend
from django.db.backends.creation import BaseDatabaseCreation from django.db.backends.creation import BaseDatabaseCreation
from django.db.backends.util import truncate_name from django.db.backends.util import truncate_name
from django.utils.log import getLogger from django.utils.log import getLogger
@ -25,12 +19,19 @@ class BaseDatabaseSchemaEditor(object):
then the relevant actions, and then commit(). This is necessary to allow then the relevant actions, and then commit(). This is necessary to allow
things like circular foreign key references - FKs will only be created once things like circular foreign key references - FKs will only be created once
commit() is called. commit() is called.
TODO:
- Repointing of FKs
- Repointing of M2Ms
- Check constraints (PosIntField)
- PK changing
""" """
# Overrideable SQL templates # Overrideable SQL templates
sql_create_table = "CREATE TABLE %(table)s (%(definition)s)" sql_create_table = "CREATE TABLE %(table)s (%(definition)s)"
sql_create_table_unique = "UNIQUE (%(columns)s)" sql_create_table_unique = "UNIQUE (%(columns)s)"
sql_rename_table = "ALTER TABLE %(old_table)s RENAME TO %(new_table)s" sql_rename_table = "ALTER TABLE %(old_table)s RENAME TO %(new_table)s"
sql_retablespace_table = "ALTER TABLE %(table)s SET TABLESPACE %(new_tablespace)s"
sql_delete_table = "DROP TABLE %(table)s CASCADE" sql_delete_table = "DROP TABLE %(table)s CASCADE"
sql_create_column = "ALTER TABLE %(table)s ADD COLUMN %(column)s %(definition)s" sql_create_column = "ALTER TABLE %(table)s ADD COLUMN %(column)s %(definition)s"
@ -261,6 +262,25 @@ class BaseDatabaseSchemaEditor(object):
"columns": ", ".join(self.quote_name(column) for column in columns), "columns": ", ".join(self.quote_name(column) for column in columns),
}) })
def alter_db_table(self, model, old_db_table, new_db_table):
"""
Renames the table a model points to.
"""
self.execute(self.sql_rename_table % {
"old_table": self.quote_name(old_db_table),
"new_table": self.quote_name(new_db_table),
})
def alter_db_tablespace(self, model, old_db_tablespace, new_db_tablespace):
"""
Moves a model's table between tablespaces
"""
self.execute(self.sql_rename_table % {
"table": self.quote_name(model._meta.db_table),
"old_tablespace": self.quote_name(old_db_tablespace),
"new_tablespace": self.quote_name(new_db_tablespace),
})
def create_field(self, model, field, keep_default=False): def create_field(self, model, field, keep_default=False):
""" """
Creates a field on a model. Creates a field on a model.

View File

@ -342,3 +342,42 @@ class SchemaTests(TestCase):
UniqueTest.objects.create(year=2012, slug="foo") UniqueTest.objects.create(year=2012, slug="foo")
self.assertRaises(IntegrityError, UniqueTest.objects.create, year=2012, slug="foo") self.assertRaises(IntegrityError, UniqueTest.objects.create, year=2012, slug="foo")
connection.rollback() connection.rollback()
def test_db_table(self):
"""
Tests renaming of the table
"""
# Create the table
editor = connection.schema_editor()
editor.start()
editor.create_model(Author)
editor.commit()
# Ensure the table is there to begin with
columns = self.column_classes(Author)
self.assertEqual(columns['name'][0], "CharField")
# Alter the table
editor = connection.schema_editor()
editor.start()
editor.alter_db_table(
Author,
"schema_author",
"schema_otherauthor",
)
editor.commit()
# Ensure the table is there afterwards
Author._meta.db_table = "schema_otherauthor"
columns = self.column_classes(Author)
self.assertEqual(columns['name'][0], "CharField")
# Alter the table again
editor = connection.schema_editor()
editor.start()
editor.alter_db_table(
Author,
"schema_otherauthor",
"schema_author",
)
editor.commit()
# Ensure the table is still there
Author._meta.db_table = "schema_author"
columns = self.column_classes(Author)
self.assertEqual(columns['name'][0], "CharField")