Skip to content

TDD: tests for index reinstatement issue #14 #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions testapp/migrations/0012_test_indexes_retained_part1.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('testapp', '0011_test_unique_constraints'),
]

# Issue #58 test prep
operations = [
migrations.CreateModel(
name='TestIndexesRetained',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('a', models.IntegerField(db_index=True)),
('b', models.IntegerField(db_index=True)),
('c', models.IntegerField(db_index=True)),
],
),
]
26 changes: 26 additions & 0 deletions testapp/migrations/0013_test_indexes_retained_part2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('testapp', '0012_test_indexes_retained_part1'),
]

# Issue #58 test operations which should leave index intact
operations = [
migrations.AlterField(
model_name='testindexesretained',
name='a',
field=models.IntegerField(db_index=True, null=True),
),
migrations.RenameField(
model_name='testindexesretained',
old_name='b',
new_name='b_renamed',
),
migrations.RenameModel(
old_name='TestIndexesRetained',
new_name='TestIndexesRetainedRenamed',
),
]
14 changes: 12 additions & 2 deletions testapp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,22 @@ class Meta:


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


class TestIndexesRetainedRenamed(models.Model):
# Issue #58 - in all these cases the column index should still exist afterwards
# case (a) `a` starts out not nullable, but then is changed to be nullable
a = models.IntegerField(db_index=True, null=True)
# case (b) column originally called `b` is renamed
b_renamed = models.IntegerField(db_index=True)
# case (c) this entire model is renamed - this is just a column whose index can be checked afterwards
c = models.IntegerField(db_index=True)


class Topping(models.Model):
name = models.UUIDField(primary_key=True, default=uuid.uuid4)

Expand Down
47 changes: 47 additions & 0 deletions testapp/tests/test_indexes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import django.db
from django.test import TestCase

from ..models import (
TestIndexesRetainedRenamed
)


class TestIndexesRetained(TestCase):
"""
Indexes dropped during a migration should be re-created afterwards
assuming the field still has `db_index=True` (issue #58)
"""

@classmethod
def setUpClass(cls):
super().setUpClass()
# Pre-fetch which indexes exist for the relevant test model
# now that all the test migrations have run
connection = django.db.connections[django.db.DEFAULT_DB_ALIAS]
cls.constraints = connection.introspection.get_constraints(
connection.cursor(),
table_name=TestIndexesRetainedRenamed._meta.db_table
)
cls.indexes = {k: v for k, v in cls.constraints.items() if v['index'] is True}

def _assert_index_exists(self, columns):
matching = {k: v for k, v in self.indexes.items() if set(v['columns']) == columns}
assert len(matching) == 1, (
"Expected 1 index for columns %s but found %d %s" % (
columns,
len(matching),
', '.join(matching.keys())
)
)

def test_field_made_nullable(self):
# Issue #58 case (a)
self._assert_index_exists({'a'})

def test_field_renamed(self):
# Issue #58 case (b)
self._assert_index_exists({'b_renamed'})

def test_table_renamed(self):
# Issue #58 case (c)
self._assert_index_exists({'c'})