Рубрики
Без рубрики

Django: мигрировать-инициализирующие фальшивые гостики

Migrate-Fake-инициал обычно используется для начала использования структуры миграций в существующей базе данных, где она будет обнаружена, если таблица уже существует, она пропустит создание таблицы и отмечает миграции в качестве применения. Но он обнаруживает таблицу в группе, поэтому одна таблица отсутствует, он предполагает, что все таблицы в миграции не существует. Tagged с Python, Django, Migration, DB.

Некоторое время мы попали, когда мы обновили старую систему сборки с Django-1.0, которая затем постепенно обновилась до 1,4, 1,8 и, наконец, теперь до 1.11 (последняя версия 1.x). Для примечаний, структура миграции базы данных приземлилась только в Django-1.7. В этой новой структуре миграции вы должны явно генерировать файлы миграции. До этого Syncdb Команда будет генерировать таблицы (которые не существует) на лету на основе определения вашей модели. Последующие изменения в таблице, такие как добавление нового столбца, следует обрабатывать вручную с помощью внешних средств.

До 1.8, имея явные файлы миграции еще не обязательны, поэтому мигрировать Команда в основном демонстрирует то же поведение, что и старый Syncdb Анкет Но так как мы обновляемся до 1.11, мы должны создать файлы миграции для всех приложений в системе. Эта первоначальная миграция в основном включала в себя создание таблиц, когда мы запускаем мигрировать командование, и, поскольку все миграции, еще не отслеживаемые, он попытается применить его, что, очевидно, потерпит неудачу, потому что все таблицы уже существуют.

По этой причине Django предоставляет 2 варианта:-

--fake¶
Tells Django to mark the migrations as having been applied or unapplied, but
without actually running the SQL to change your database schema.

This is intended for advanced users to manipulate the current migration state
directly if they're manually applying changes; be warned that using --fake runs the
risk of putting the migration state table into a state where manual recovery will
be needed to make migrations run correctly.

--fake-initial¶
Allows Django to skip an app's initial migration if all database tables with the
names of all models created by all CreateModel operations in that migration already
exist. This option is intended for use when first running migrations against a
database that preexisted the use of migrations. This option does not, however,
check for matching database schema beyond matching table names and so is only safe
to use if you are confident that your existing schema matches what is recorded in
your initial migration.

Мы решили использовать -Факе-инициал Для мигрировать . Но мы получили таблицу ошибок уже существует. Сначала это не имеет смысла, как мы можем прочитать выше, он обнаружит, существует ли таблица, а затем просто «подделка применить» миграции. И мы точно знаем, что таблица действительно существует, так почему Джанго все еще хочет создать эту таблицу?

Я прошел через код миграции в django/db/migrations/executor.py и положить pdb.set_trace () В этой части:-

        # Make sure all create model and add field operations are done
        for operation in migration.operations:
            import pdb;pdb.set_trace()
            if isinstance(operation, migrations.CreateModel):
                model = apps.get_model(migration.app_label, operation.name)
                if model._meta.swapped:

Пройдя через это, и, к счастью, ошибка произошла довольно рано, я вижу, что правильно обнаружил, что таблица существует:-

(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(337)detect_soft_applied()
-> if should_skip_detecting_model(migration, model):
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(339)detect_soft_applied()
-> if model._meta.db_table not in existing_table_names:
(Pdb) l
334                         # We have to fetch the model to test with from the
335                         # main app cache, as it's not a direct dependency.
336                         model = global_apps.get_model(model._meta.swapped)
337                     if should_skip_detecting_model(migration, model):
338                         continue
339  ->                 if model._meta.db_table not in existing_table_names:
340                         return False, project_state
341                     found_create_model_migration = True
342                 elif isinstance(operation, migrations.AddField):
343                     model = apps.get_model(migration.app_label, operation.model_name)
344                     if model._meta.swapped:
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(341)detect_soft_applied()
-> found_create_model_migration = True

Пока это не дойдет до этой итерации:-

> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(330)detect_soft_applied()
-> import pdb;pdb.set_trace()
(Pdb) operation.name
'Image'
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(331)detect_soft_applied()
-> if isinstance(operation, migrations.CreateModel):
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(332)detect_soft_applied()
-> model = apps.get_model(migration.app_label, operation.name)
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(333)detect_soft_applied()
-> if model._meta.swapped:
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(337)detect_soft_applied()
-> if should_skip_detecting_model(migration, model):
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(339)detect_soft_applied()
-> if model._meta.db_table not in existing_table_names:
(Pdb) n
> /home/kamal/.local/lib/python3.4/site-packages/django/db/migrations/executor.py(340)detect_soft_applied()
-> return False, project_state

Так почему он обнаружил таблицу как не существует? Осмотр переменной Существующий_TABLE_NAMES Наконец -то дал мне свет. Таблица действительно не существует!

(Pdb) model._meta.db_table not in existing_table_names
True
(Pdb) model._meta.db_table
'blog_image'
(Pdb) existing_table_names
['auth_group', 'auth_group_permissions', 'auth_permission', 'auth_user', 'auth_user_groups', 'auth_user_user_permissions', 'blog_article', 'django_admin_log', 'django_content_type', 'django_migrations', 'django_session']

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

Оригинал: “https://dev.to/k4ml/django-migrate—fake-initial-gotchas-2fih”