Skip to content

Commit e87757f

Browse files
authored
Merge pull request #49 from sparrowt/index-reinstatement-broken
TDD: tests for index reinstatement issue #14
2 parents 5108884 + 70bcb3a commit e87757f

File tree

4 files changed

+106
-2
lines changed

4 files changed

+106
-2
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from django.db import migrations, models
2+
3+
4+
class Migration(migrations.Migration):
5+
6+
dependencies = [
7+
('testapp', '0011_test_unique_constraints'),
8+
]
9+
10+
# Issue #58 test prep
11+
operations = [
12+
migrations.CreateModel(
13+
name='TestIndexesRetained',
14+
fields=[
15+
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
16+
('a', models.IntegerField(db_index=True)),
17+
('b', models.IntegerField(db_index=True)),
18+
('c', models.IntegerField(db_index=True)),
19+
],
20+
),
21+
]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from django.db import migrations, models
2+
3+
4+
class Migration(migrations.Migration):
5+
6+
dependencies = [
7+
('testapp', '0012_test_indexes_retained_part1'),
8+
]
9+
10+
# Issue #58 test operations which should leave index intact
11+
operations = [
12+
migrations.AlterField(
13+
model_name='testindexesretained',
14+
name='a',
15+
field=models.IntegerField(db_index=True, null=True),
16+
),
17+
migrations.RenameField(
18+
model_name='testindexesretained',
19+
old_name='b',
20+
new_name='b_renamed',
21+
),
22+
migrations.RenameModel(
23+
old_name='TestIndexesRetained',
24+
new_name='TestIndexesRetainedRenamed',
25+
),
26+
]

testapp/models.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,22 @@ class Meta:
7171

7272

7373
class TestRemoveOneToOneFieldModel(models.Model):
74-
# Fields used for testing removing OneToOne field. Verifies that delete_unique do not try to remove indexes
75-
# thats already is removed.
74+
# Fields used for testing removing OneToOne field. Verifies that delete_unique does not try to remove
75+
# indexes that have already been removed (Issue #51)
7676
# b = models.OneToOneField('self', on_delete=models.SET_NULL, null=True)
7777
a = models.CharField(max_length=50)
7878

7979

80+
class TestIndexesRetainedRenamed(models.Model):
81+
# Issue #58 - in all these cases the column index should still exist afterwards
82+
# case (a) `a` starts out not nullable, but then is changed to be nullable
83+
a = models.IntegerField(db_index=True, null=True)
84+
# case (b) column originally called `b` is renamed
85+
b_renamed = models.IntegerField(db_index=True)
86+
# case (c) this entire model is renamed - this is just a column whose index can be checked afterwards
87+
c = models.IntegerField(db_index=True)
88+
89+
8090
class Topping(models.Model):
8191
name = models.UUIDField(primary_key=True, default=uuid.uuid4)
8292

testapp/tests/test_indexes.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import django.db
2+
from django.test import TestCase
3+
4+
from ..models import (
5+
TestIndexesRetainedRenamed
6+
)
7+
8+
9+
class TestIndexesRetained(TestCase):
10+
"""
11+
Indexes dropped during a migration should be re-created afterwards
12+
assuming the field still has `db_index=True` (issue #58)
13+
"""
14+
15+
@classmethod
16+
def setUpClass(cls):
17+
super().setUpClass()
18+
# Pre-fetch which indexes exist for the relevant test model
19+
# now that all the test migrations have run
20+
connection = django.db.connections[django.db.DEFAULT_DB_ALIAS]
21+
cls.constraints = connection.introspection.get_constraints(
22+
connection.cursor(),
23+
table_name=TestIndexesRetainedRenamed._meta.db_table
24+
)
25+
cls.indexes = {k: v for k, v in cls.constraints.items() if v['index'] is True}
26+
27+
def _assert_index_exists(self, columns):
28+
matching = {k: v for k, v in self.indexes.items() if set(v['columns']) == columns}
29+
assert len(matching) == 1, (
30+
"Expected 1 index for columns %s but found %d %s" % (
31+
columns,
32+
len(matching),
33+
', '.join(matching.keys())
34+
)
35+
)
36+
37+
def test_field_made_nullable(self):
38+
# Issue #58 case (a)
39+
self._assert_index_exists({'a'})
40+
41+
def test_field_renamed(self):
42+
# Issue #58 case (b)
43+
self._assert_index_exists({'b_renamed'})
44+
45+
def test_table_renamed(self):
46+
# Issue #58 case (c)
47+
self._assert_index_exists({'c'})

0 commit comments

Comments
 (0)