From ae19315b4d8a19eda07ea8f313c485ca0a7875d0 Mon Sep 17 00:00:00 2001 From: Andrew Godwin Date: Sun, 11 Aug 2013 14:23:31 +0100 Subject: [PATCH] Support index_together during model creation --- django/db/backends/schema.py | 9 +++++++++ django/db/backends/sqlite3/introspection.py | 5 ++++- tests/schema/models.py | 9 +++++++++ tests/schema/tests.py | 19 ++++++++++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/django/db/backends/schema.py b/django/db/backends/schema.py index 1e1376a4e2e..d868bf79b56 100644 --- a/django/db/backends/schema.py +++ b/django/db/backends/schema.py @@ -210,6 +210,15 @@ class BaseDatabaseSchemaEditor(object): "definition": ", ".join(column_sqls) } self.execute(sql, params) + # Add any index_togethers + for fields in model._meta.index_together: + columns = [model._meta.get_field_by_name(field)[0].column for field in fields] + self.execute(self.sql_create_index % { + "table": self.quote_name(model._meta.db_table), + "name": self._create_index_name(model, columns, suffix="_idx"), + "columns": ", ".join(self.quote_name(column) for column in columns), + "extra": "", + }) # Make M2M tables for field in model._meta.local_many_to_many: self.create_model(field.rel.through) diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py index 2e674bc05bd..92777dd910a 100644 --- a/django/db/backends/sqlite3/introspection.py +++ b/django/db/backends/sqlite3/introspection.py @@ -168,7 +168,10 @@ class DatabaseIntrospection(BaseDatabaseIntrospection): """ # Don't use PRAGMA because that causes issues with some transactions cursor.execute("SELECT sql FROM sqlite_master WHERE tbl_name = %s AND type = %s", [table_name, "table"]) - results = cursor.fetchone()[0].strip() + row = cursor.fetchone() + if row is None: + raise ValueError("Table %s does not exist" % table_name) + results = row[0].strip() results = results[results.index('(') + 1:results.rindex(')')] for field_desc in results.split(','): field_desc = field_desc.strip() diff --git a/tests/schema/models.py b/tests/schema/models.py index a160b9aaa8f..69cf06f3c4c 100644 --- a/tests/schema/models.py +++ b/tests/schema/models.py @@ -62,6 +62,15 @@ class Tag(models.Model): app_cache = new_app_cache +class TagIndexed(models.Model): + title = models.CharField(max_length=255) + slug = models.SlugField(unique=True) + + class Meta: + app_cache = new_app_cache + index_together = [["slug", "title"]] + + class TagUniqueRename(models.Model): title = models.CharField(max_length=255) slug2 = models.SlugField(unique=True) diff --git a/tests/schema/tests.py b/tests/schema/tests.py index 3a82cd15ff0..f6e45599b8f 100644 --- a/tests/schema/tests.py +++ b/tests/schema/tests.py @@ -6,7 +6,7 @@ from django.db import connection, DatabaseError, IntegrityError from django.db.models.fields import IntegerField, TextField, CharField, SlugField from django.db.models.fields.related import ManyToManyField, ForeignKey from django.db.transaction import atomic -from .models import Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagUniqueRename, UniqueTest +from .models import Author, AuthorWithM2M, Book, BookWithSlug, BookWithM2M, Tag, TagIndexed, TagUniqueRename, UniqueTest class SchemaTests(TransactionTestCase): @@ -503,6 +503,23 @@ class SchemaTests(TransactionTestCase): ), ) + def test_create_index_together(self): + """ + Tests creating models with index_together already defined + """ + # Create the table + with connection.schema_editor() as editor: + editor.create_model(TagIndexed) + # Ensure there is an index + self.assertEqual( + True, + any( + c["index"] + for c in connection.introspection.get_constraints(connection.cursor(), "schema_tagindexed").values() + if c['columns'] == ["slug", "title"] + ), + ) + def test_db_table(self): """ Tests renaming of the table