Некоторое время мы попали, когда мы обновили старую систему сборки с 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”