Колонка миграции Django не существует Ошибка ProgrammingError при выполнении тестов

Я столкнулся с ошибкой при тестировании приложения django с помощью pytest, а точнее при запуске тестов, если я выполнил миграцию, которая удаляет поле, использованное в более ранней миграции. Если сделать это вне тестов, то ошибка не возникает.

Для размножения:

models.py
from django.db import models

class TestModel(models.Model):
    # We started with this field, but now longer need it
    # original_text = models.CharField(max_length=255)
    # We added this field and then moved over to it
    new_text = models.CharField(max_length=511)
migrations/0001_initial.py
from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
    ]

    operations = [
        migrations.CreateModel(
            name='TestModel',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('original_text', models.CharField(max_length=255)),
            ],
        ),
    ]
migrations/0002_testmodel_new_text.py
from django.db import migrations, models


def move_text_to_other_field_and_append_new(apps, schema_editor):
    TestModel = apps.get_model("sample", "TestModel")

    for test_model in TestModel.objects.all():
        test_model.new_text = test_model.original_text + " new"
        test_model.save()

class Migration(migrations.Migration):

    dependencies = [
        ('sample', '0001_initial'),
    ]

    operations = [
        migrations.AddField(
            model_name='testmodel',
            name='new_text',
            field=models.CharField(default='', max_length=511),
            preserve_default=False,
        ),
        migrations.RunPython(move_text_to_other_field_and_append_new, migrations.RunPython.noop)
    ]
migrations/0003_remove_testmodel_original_text.py
from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('sample', '0002_testmodel_new_text'),
    ]

    operations = [
        migrations.RemoveField(
            model_name='testmodel',
            name='original_text',
        ),
    ]
tests.py
from django.test import TestCase


class TestModelTestCase(TestCase):

    def test_example(self):
        self.assertEqual(1, 1)

Это минимальная настройка для воспроизведения ошибки. Теперь при выполнении pipenv run pytest sample/tests.py я получаю ошибку ERROR sample/tests.py::TestModelTestCase::test_example - django.db.utils.ProgrammingError: column sample_testmodel.original_text does not exist. В стеке ошибок четко указано следующее:

sample/migrations/0002_testmodel_new_text.py:9: in move_text_to_other_field_and_append_new
    for test_model in TestModel.objects.all():

И затем:

self = <django.db.backends.utils.CursorWrapper object at 0x7f3e53a40e80>, sql = 'SELECT "sample_testmodel"."id", "sample_testmodel"."original_text", "sample_testmodel"."new_text" FROM "sample_testmodel"', params = ()
ignored_wrapper_args = (False, {'connection': <django.db.backends.postgresql.base.DatabaseWrapper object at 0x7f3e5d7e5d90>, 'cursor': <django.db.backends.utils.CursorWrapper object at 0x7f3e53a40e80>})

    def _execute(self, sql, params, *ignored_wrapper_args):
        self.db.validate_no_broken_transaction()
        with self.db.wrap_database_errors:
            if params is None:
                # params default might be backend specific.
                return self.cursor.execute(sql)
            else:
>               return self.cursor.execute(sql, params)
E               django.db.utils.ProgrammingError: column sample_testmodel.original_text does not exist
E               LINE 1: SELECT "sample_testmodel"."id", "sample_testmodel"."original...
E                                                       ^

../../../.local/share/virtualenvs/sprancher-wR5ufyMh/lib/python3.8/site-packages/django/db/backends/utils.py:84: ProgrammingError

Это беспокоит меня уже долгое время. Это происходит только в тестах. Комментирование строки RunPython в 0002 помогло, но это явно не долгосрочное решение. Запуск тестов перед добавлением 0003 выдает зеленый свет, до этого момента проблем не было. Порядок выполнения кажется мне неправильным или что-то в этом роде, но я никак не могу понять, в чем дело.

Мой вопрос в том, почему это происходит и как я могу предотвратить это?

Вернуться на верх