1
0
mirror of https://github.com/django/django.git synced 2025-10-24 06:06:09 +00:00

Fixed #26808 -- Added Meta.indexes for class-based indexes.

* Added the index name to its deconstruction.
* Added indexes to sqlite3.schema._remake_table() so that indexes
  aren't dropped when _remake_table() is called.

Thanks timgraham & MarkusH for review and advice.
This commit is contained in:
Akshesh
2016-06-20 21:20:05 +05:30
committed by Tim Graham
parent d117567c7d
commit 6a8372e6ec
14 changed files with 246 additions and 35 deletions

View File

@@ -370,6 +370,20 @@ class AutodetectorTests(TestCase):
("authors", models.ManyToManyField("testapp.Author", through="otherapp.Attribution")),
("title", models.CharField(max_length=200)),
])
book_indexes = ModelState("otherapp", "Book", [
("id", models.AutoField(primary_key=True)),
("author", models.ForeignKey("testapp.Author", models.CASCADE)),
("title", models.CharField(max_length=200)),
], {
"indexes": [models.Index(fields=["author", "title"], name="book_title_author_idx")],
})
book_unordered_indexes = ModelState("otherapp", "Book", [
("id", models.AutoField(primary_key=True)),
("author", models.ForeignKey("testapp.Author", models.CASCADE)),
("title", models.CharField(max_length=200)),
], {
"indexes": [models.Index(fields=["title", "author"], name="book_author_title_idx")],
})
book_foo_together = ModelState("otherapp", "Book", [
("id", models.AutoField(primary_key=True)),
("author", models.ForeignKey("testapp.Author", models.CASCADE)),
@@ -432,7 +446,10 @@ class AutodetectorTests(TestCase):
("id", models.AutoField(primary_key=True)),
("knight", models.ForeignKey("eggs.Knight", models.CASCADE)),
("parent", models.ForeignKey("eggs.Rabbit", models.CASCADE)),
], {"unique_together": {("parent", "knight")}})
], {
"unique_together": {("parent", "knight")},
"indexes": [models.Index(fields=["parent", "knight"], name='rabbit_circular_fk_index')],
})
def repr_changes(self, changes, include_dependencies=False):
output = ""
@@ -978,16 +995,18 @@ class AutodetectorTests(TestCase):
self.assertOperationAttributes(changes, "testapp", 0, 2, name="publisher")
self.assertMigrationDependencies(changes, 'testapp', 0, [])
def test_same_app_circular_fk_dependency_and_unique_together(self):
def test_same_app_circular_fk_dependency_with_unique_together_and_indexes(self):
"""
#22275 - Tests that a migration with circular FK dependency does not try
to create unique together constraint before creating all required fields
first.
to create unique together constraint and indexes before creating all
required fields first.
"""
changes = self.get_changes([], [self.knight, self.rabbit])
# Right number/type of migrations?
self.assertNumberMigrations(changes, 'eggs', 1)
self.assertOperationTypes(changes, 'eggs', 0, ["CreateModel", "CreateModel", "AlterUniqueTogether"])
self.assertOperationTypes(
changes, 'eggs', 0, ["CreateModel", "CreateModel", "AddIndex", "AlterUniqueTogether"]
)
self.assertNotIn("unique_together", changes['eggs'][0].operations[0].options)
self.assertNotIn("unique_together", changes['eggs'][0].operations[1].options)
self.assertMigrationDependencies(changes, 'eggs', 0, [])
@@ -1135,6 +1154,51 @@ class AutodetectorTests(TestCase):
for t in tests:
test(*t)
def test_create_model_with_indexes(self):
"""Test creation of new model with indexes already defined."""
author = ModelState('otherapp', 'Author', [
('id', models.AutoField(primary_key=True)),
('name', models.CharField(max_length=200)),
], {'indexes': [models.Index(fields=['name'], name='create_model_with_indexes_idx')]})
changes = self.get_changes([], [author])
added_index = models.Index(fields=['name'], name='create_model_with_indexes_idx')
# Right number of migrations?
self.assertEqual(len(changes['otherapp']), 1)
# Right number of actions?
migration = changes['otherapp'][0]
self.assertEqual(len(migration.operations), 2)
# Right actions order?
self.assertOperationTypes(changes, 'otherapp', 0, ['CreateModel', 'AddIndex'])
self.assertOperationAttributes(changes, 'otherapp', 0, 0, name='Author')
self.assertOperationAttributes(changes, 'otherapp', 0, 1, model_name='author', index=added_index)
def test_add_indexes(self):
"""Test change detection of new indexes."""
changes = self.get_changes([self.author_empty, self.book], [self.author_empty, self.book_indexes])
self.assertNumberMigrations(changes, 'otherapp', 1)
self.assertOperationTypes(changes, 'otherapp', 0, ['AddIndex'])
added_index = models.Index(fields=['author', 'title'], name='book_title_author_idx')
self.assertOperationAttributes(changes, 'otherapp', 0, 0, model_name='book', index=added_index)
def test_remove_indexes(self):
"""Test change detection of removed indexes."""
changes = self.get_changes([self.author_empty, self.book_indexes], [self.author_empty, self.book])
# Right number/type of migrations?
self.assertNumberMigrations(changes, 'otherapp', 1)
self.assertOperationTypes(changes, 'otherapp', 0, ['RemoveIndex'])
self.assertOperationAttributes(changes, 'otherapp', 0, 0, model_name='book', name='book_title_author_idx')
def test_order_fields_indexes(self):
"""Test change detection of reordering of fields in indexes."""
changes = self.get_changes(
[self.author_empty, self.book_indexes], [self.author_empty, self.book_unordered_indexes]
)
self.assertNumberMigrations(changes, 'otherapp', 1)
self.assertOperationTypes(changes, 'otherapp', 0, ['RemoveIndex', 'AddIndex'])
self.assertOperationAttributes(changes, 'otherapp', 0, 0, model_name='book', name='book_title_author_idx')
added_index = models.Index(fields=['title', 'author'], name='book_author_title_idx')
self.assertOperationAttributes(changes, 'otherapp', 0, 1, model_name='book', index=added_index)
def test_add_foo_together(self):
"""Tests index/unique_together detection."""
changes = self.get_changes([self.author_empty, self.book], [self.author_empty, self.book_foo_together])