Каков наилучший способ разрешения Rails-сиротских миграций?
Я переключался между ветвями в проекте и каждый из них имел разные миграции... Это сценарий:
$rake db: migrate: status
Status Migration ID Migration Name
--------------------------------------------------
...
up 20130307154128 Change columns in traffic capture
up 20130311155109 Remove log settings
up 20130311160901 Remove log alarm table
up 20130320144219 ********** NO FILE **********
up 20130320161939 ********** NO FILE **********
up 20130320184628 ********** NO FILE **********
up 20130322004817 Add replicate to root settings
up 20130403190042 ********** NO FILE **********
up 20130403195300 ********** NO FILE **********
up 20130403214000 ********** NO FILE **********
up 20130405164752 Fix ap hostnames
up 20130410194222 ********** NO FILE **********
Проблема rake db:rollback
не работает вообще из-за недостающих файлов...
Что мне делать, чтобы снова откатиться и избавиться от сообщений NO FILE?
Btw, rake db:reset
или rake db:drop
не являются опцией, я не могу потерять данные из других таблиц...
Ответы
Ответ 1
Я решил решить эту проблему следующим образом:
(1) Перейдите в ветки с файлами миграции и отложите их. Это не тривиально, когда у вас много ветвей, которые приведут к конфликтам, если вы попытаетесь объединить их. Поэтому я использую эти команды, чтобы узнать, к каким ветвям каждой сиротской миграции принадлежит.
Итак, мне нужно найти фиксацию последнего изменения миграции.
git log --all --reverse --stat | grep <LASTEST_ORPHAN_MIGRATION_ID> -C 10
Я беру хэш хеширования и определяю, какая ветка принадлежит ему:
git branch --contains <COMMIT_HASH>
Затем я могу вернуться к этой ветке, выполнить откат и повторить этот процесс для всех отсутствующих файлов.
(2) Запуск миграции: проверьте ветвь, в которой вы, наконец, хотите работать и выполняете миграцию, и вам должно быть хорошо идти.
Устранение неполадок
В некоторых случаях я также запускал сиротские миграции, где на удаленных ветвях.
Чтобы решить эту проблему, я создал фиктивные файлы миграции с одним и тем же mig_id отсутствующих файлов и отбросил их назад. После этого я смог удалить их фиктивные миграции и иметь чистый статус миграции:)
Другой альтернативой является удаление отсутствующих файлов из базы данных напрямую:
delete from schema_migrations where version='<MIGRATION_ID>';
Ответ 2
Миграции хранятся в вашей базе данных. Если вы хотите удалить заброшенные миграции, удалите их из db.
Пример для Postgres:
-
Открыть psql:
psql
-
Подключитесь к своему db:
\c your_database
-
Если вам интересно, отобразите schema_migrations:
SELECT * FROM schema_migrations;
-
Если вам интересно, проверьте, нет ли оставленных миграций:
SELECT version FROM schema_migrations WHERE version IN
('20130320144219', '20130320161939', '20130320184628', '20130403190042',
'20130403195300', '20130403214000', '20130410194222');
-
Удалите их:
DELETE FROM schema_migrations WHERE version IN (<version list as above>);
Теперь, если вы запустите bundle exec rake db:migrate:status
, вы увидите, что потерянные оси были успешно удалены.
Ответ 3
Изменить: Как сказано в комментариях, следующие УБЫТЬ ВАШУ БАЗУ ДАННЫХ
Более простой подход, который сработал у меня (обратите внимание, что эта команда удалит базу данных, и все ваши данные будут потеряны):
rake db:migrate:reset
.. и затем:
rake db:migrate:status
Сирота (ов) должна исчезнуть.
Ответ 4
Предполагая, что вы используете Git, должно быть относительно просто захватить эти миграции и привести их в текущую ветку. Если у вас есть конкретная фиксация, из которой вы хотите получить файл, вы можете использовать:
git checkout <commit hash> <file_name>
(Спасибо этот ответ)
В качестве альтернативы вы можете проверить из определенной ветки HEAD:
git checkout <branch name> -- <file_name>
В соответствии с этим сообщением
Предполагая, что на самом деле это версии миграций, запущенных в базе данных, вы должны быть хороши для отката.
Ответ 5
Вы можете объединить две ветки назад в мастер, чтобы все доступные миграции были доступны. Если вы действительно не хотите эти миграции там, но хотите иметь возможность отката, вы можете отредактировать таблицу schema_migrations в своей базе данных, чтобы удалить строки, соответствующие миграциям, для которых у вас нет файлов. Однако это вызовет проблемы, если вы затем переключитесь на другую ветку с разными миграциями.
Ответ 6
Если файлы миграции действительно отсутствуют (например, прогон миграции, забыл отменить миграцию, затем удалил файл миграции до фиксации), я смог воспроизвести недостающую миграцию следующим образом:
- вернуться в историю git, чтобы получить копию файла schema.rb и сохранить за пределами git repo (
git log; git checkout xxxxxx; cp schema.rb ~/schema_old.rb, git checkout master)
.
- запустите diff для двух файлов и скопируйте команды миграции в файл миграции, который соответствует отсутствующему идентификатору миграции (
diff schema.rb ~/schema_old.rb > migration_file.rb; vi migration_file.rb
)
- Проверьте статус миграции и откат (
rake db:migrate:status; rake db:rollback; rake db:migrate:status;
)
Ответ 7
Вот рейк-версия ответа psql, которая не сотрет вашу БД и не сделает ничего сумасшедшего:
1) Найдите свои версии осиротевшей миграции:
rails db: мигрировать: статус
2) Обратите внимание на версии отсутствующих миграций и перейдите в консоль db:
rails dbconsole
3) Теперь удалите версии из таблицы миграции вручную:
удалить из schema_migrations, где version = '[version_number]';