Django TestCase без некоторых миграций - PullRequest
0 голосов
/ 09 июля 2020

По какой-то причине Django (3.0.7,8) не выполняет одну из моих миграций users.0002_customuser_is_service_account при выполнении TestCase. Он не ошибается, он просто игнорирует его. Эта миграция была успешно применена к моей базе данных разработки, и при нормальных обстоятельствах команда migrate обнаруживает ее без проблем.

Вернуться к исходному состоянию:

python manage.py migrate users 0001
Operations to perform:
  Target specific migration: 0001_initial, from users
Running migrations:
  Rendering model states... DONE
  Unapplying users.0002_customuser_is_service_account... OK

Повторно применить автоматически -обнаружение миграции

 python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, csv_management, reversion, sessions, softdelete, tasks, trades, trades_portal, users
Running migrations:
  Applying users.0002_customuser_is_service_account... OK

Миграции в базе данных разработки: enter image description here

But when I attempt to run this simple TestCase, it complains that it cannot find a column.

from django.test import TestCase
from users.models import CustomUser

class TestExists(TestCase):
    def test_thing(self):
        CustomUser.objects.all()
python manage.py test trades_portal --no-input

django.db.utils.ProgrammingError: column "is_service_account" of relation "users_customuser" does not exist
LINE 1: ... "email", "is_staff", "is_active", "date_joined", "is_servic...

Если я посмотрю на тестовую базу данных после того, как тест завершится неудачно, конечно же, этот столбец не существует: enter image description here

And looking in the migrations, the migration which adds that column was never run: enter image description here

Here is the migration:

# Generated by Django 3.0.7 on 2020-06-12 14:50

from django.db import migrations, models


class Migration(migrations.Migration):

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

    operations = [
        migrations.AddField(
            model_name='customuser',
            name='is_service_account',
            field=models.BooleanField(default=False, help_text='Designation for whether this account receives certain actions, such as receiving emails for all users.', verbose_name='Is Service Account'),
        ),
    ]

Дело в том, что я пытался воссоздать эту проблему в другом проекте, но не смог. Все миграции применяются, и тест проходит успешно. Я совершенно не понимаю, что здесь происходит.

1 Ответ

1 голос
/ 09 июля 2020

Оказывается, что

dependencies = [
    migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]

, указанное как часть миграции, не гарантирует, что все миграции пользовательской модели будут выполнены до выполнения этой миграции. Это только кажется, что гарантирует, что custom_user.migrations.0001_initial запущен.

Из-за этого, когда миграция фактически пытается получить или создать такого настраиваемого пользователя, используя настраиваемую модель пользователя в качестве одной из своих операций, вы не Гарантировано, что все миграции пользовательских моделей выполнены. Такой пример приведен ниже.

def add_initial_auth(apps, schema_editor):

    Group = apps.get_model('auth', 'Group')
    User = get_user_model()
    initial_groups = INITIAL_GROUPS

    existing_groups = list(Group.objects.filter(name__in=initial_groups).values_list('name', flat=True))

    Group.objects.bulk_create(
        [Group(name=group_name) for group_name in initial_groups if group_name not in existing_groups]
    )

    _ = User.objects.create_superuser(username=settings.INITIAL_ADMIN_USERNAME,
                                      password=settings.INITIAL_ADMIN_PASSWORD,
                                      email=settings.INITIAL_ADMIN_EMAIL)


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [migrations.RunPython(add_initial_auth)]

Решение, к сожалению, состоит в том, что вы должны указать последнюю миграцию как зависимость:

dependencies = [
    migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ('users', '0002_customuser_is_service_account')
]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...