Подтвердить что ты не робот

Каков наилучший способ разрешения 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 не являются опцией, я не могу потерять данные из других таблиц...

4b9b3361

Ответ 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]';