Commit 60873ea2 authored by Andrew Godwin's avatar Andrew Godwin
Browse files

Add db_table and db_tablespace handling

parent 184cf9ab
Loading
Loading
Loading
Loading
+26 −6
Original line number Diff line number Diff line
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.util import truncate_name
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
    things like circular foreign key references - FKs will only be created once
    commit() is called.

    TODO:
        - Repointing of FKs
        - Repointing of M2Ms
        - Check constraints (PosIntField)
        - PK changing
    """

    # Overrideable SQL templates
    sql_create_table = "CREATE TABLE %(table)s (%(definition)s)"
    sql_create_table_unique = "UNIQUE (%(columns)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_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),
            })

    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):
        """
        Creates a field on a model.
+39 −0
Original line number Diff line number Diff line
@@ -342,3 +342,42 @@ class SchemaTests(TestCase):
        UniqueTest.objects.create(year=2012, slug="foo")
        self.assertRaises(IntegrityError, UniqueTest.objects.create, year=2012, slug="foo")
        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")