Как откатить конкретную миграцию?


808

У меня есть следующий файл миграции db\migrate\20100905201547_create_blocks.rb

Как конкретно откатить этот файл миграции?


1
Это решает проблему? Вам просто нужно будет выполнить Class.down stackoverflow.com/questions/753919/run-a-single-migration-file
danivovich

4
Вся

1
Вы хотите откатить только эту конкретную миграцию (даже если после нее появятся более новые миграции)? Или вы хотите откатить базу данных до того состояния, в котором она находилась до этой миграции и любых последующих миграций?
Джон Шнайдер

Ответы:


1342
rake db:rollback STEP=1

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

Например:

rake db:rollback STEP=5

Также будет выполнен откат всей миграции, произошедшей позже (4, 3, 2, а также 1).

Чтобы откатить все миграции обратно (и включая) целевую миграцию, используйте: (Эта исправленная команда была добавлена ​​ПОСЛЕ всех комментариев, указывающих на ошибку в исходном сообщении)

rake db:migrate VERSION=20100905201547

Чтобы откатить ТОЛЬКО ОДНУ конкретную миграцию (OUT OF ORDER), используйте:

rake db:migrate:down VERSION=20100905201547

Обратите внимание, что это НЕ отменит любые промежуточные миграции - только тот, который указан. Если это не то, что вы намеревались, вы можете безопасно запустить, rake db:migrateи он будет перезапущен только тот, пропуская другие, которые ранее не были откатаны.

И если вы когда-нибудь захотите перенести одну миграцию не по порядку, есть и обратная сторона db:migrate:up:

rake db:migrate:up VERSION=20100905201547

14
«Чтобы выполнить откат к определенной версии» - разве команда, которая следует, только откатывает определенную миграцию, вместо того, чтобы полностью откатиться к этой версии?
Эндрю Гримм

10
«Для отката на конкретную версию используйте ...» Этот ответ неверен! Это откатит миграцию изолированно, как объяснено другими ответами.
Рис ван дер Варден

3
ПРЕДУПРЕЖДЕНИЕ: я сделал эту ошибку: используйте только rake db: migrate: down VERSION = 20100905201547 для отката в ИЗОЛЯЦИИ !!! один файл миграции. Это упомянуто в комментарии выше, но я пропустил это.
pixelearth

3
Еще одно предупреждение - никогда не делай STEP=-1. Я сделал это однажды, и это сошло с ума, откатывая все назад. Не хорошо! Это был Rails 4.2 - думаю, это может быть исправлено.
Дэйв Хартнолл,

1
Написал в моем блоге статью о миграциях, в которой объясняется, как и когда использовать эти команды: railsguides.net/polish-rails-migrations
ka8725

868
rake db:migrate:down VERSION=20100905201547

откатит конкретный файл.


Чтобы найти версию всех миграций, вы можете использовать эту команду:

rake db:migrate:status

Или просто префикс имени файла миграции - это версия, которую нужно откатить.


См. Руководство по Ruby on Rails по миграции.


48
Определенно предпочтительный ответ на мой взгляд.
streetlogics

30
Стоит отметить, что если вы откатываете конкретную миграцию и не хотите, чтобы она была перенастроена при следующих задачах с граблями, то удалите также файл миграции.
BradGreens

4
Примечание: кажется, что если миграция вверх никогда не выполнялась, а выполнялась только частично, операция вниз ничего не делает.
Cyrilchampier

1
@nerith, это, вероятно, верно только для баз данных, которые не поддерживают транзакционный DDL. MySQL не поддерживает транзакционный DDL: dev.mysql.com/doc/refman/5.0/en/cannot-roll-back.html PostreSQL делает: wiki.postgresql.org/wiki/… Так что если ваша миграция в базе данных MySQL нарушена Затем вы должны вручную удалить часть миграции, которая прошла успешно.
Иван Бишевац

1
Еще одно замечание относительно комментария @BradGreens. Если вы действительно хотите удалить файл миграции, и он уже был развернут, вам нужно будет откатить производство / промежуточное выполнение до того, как вы передадите код с удаленным файлом. В противном случае вы не сможете выполнить откат / миграцию: вниз.
AdamT

57

Для отката последней миграции вы можете сделать:

rake db:rollback

Если вы хотите откатить определенную миграцию с версией, вы должны сделать:

rake db:migrate:down VERSION=YOUR_MIGRATION_VERSION

Например, если версия 20141201122027, вы будете делать:

rake db:migrate:down VERSION=20141201122027

откатить эту конкретную миграцию.


32

Вы можете откатить миграцию, используя rake db:rollbackразличные параметры. Синтаксис будет отличаться в зависимости от ваших требований.

Если вы хотите откатить только последнюю миграцию, то вы можете использовать либо

rake db:rollback

или

rake db:rollback STEP=1

Если вы хотите откатить количество миграций сразу, вы просто передаете аргумент:

rake db:rollback STEP=n

где nчисло миграций для отката, считая от последней миграции.

Если вы хотите выполнить откат к определенной миграции, вы должны передать версию миграции следующим образом:

rake db:migrate:down VERSION=xxxxx

где xxxxx - номер версии миграции.


1
добавление: вниз не работает, правильный ответ без вниз
Elta3lab

26

rake db:migrate:down VERSION=your_migrations's_version_number_here

Версия - это числовой префикс в имени файла миграции.

Как найти версию :

Ваши файлы миграции хранятся в вашем rails_root/db/migrateкаталоге. Найдите подходящий файл, до которого вы хотите выполнить откат, и скопируйте номер префикса.

например

имя файла: 20140208031131_create_roles.rb тогда версия20140208031131


6
Самый простой способ найти идентификатор миграции - запуститьrake db:migrate:status
Aeradriel

18

Откат последней миграции:

# rails < 5.0
rake db:rollback

# rails >= 5.0
rake db:rollback
# or
rails db:rollback

Откат последнего nколичества миграций

# rails < 5.0
rake db:rollback STEP=2

# rails >= 5.0
rake db:rollback STEP=2
# or
rails db:rollback STEP=2

Откат определенной миграции

# rails < 5.0
rake db:migrate:down VERSION=20100905201547

# rails >= 5.0
rake db:migrate:down VERSION=20100905201547
# or
rails db:migrate:down VERSION=20100905201547

14

Для отката последней миграции вы можете сделать:

rake db:rollback

Если вы хотите откатить определенную миграцию с версией, вы должны сделать:

rake db:migrate:down VERSION=YOUR_MIGRATION_VERSION

Если файл миграции, который вы хотите откатить, был вызван db/migrate/20141201122027_create_some_table.rb, то VERSION для этой миграции - 20141201122027это отметка времени, когда была создана эта миграция, и команда для отката этой миграции будет:

rake db:migrate:down VERSION=20141201122027

6

Если это обратимая миграция и последняя, ​​которая была выполнена, запустите rake db:rollback. И вы всегда можете использовать версию. например

файл миграции - 20140716084539_create_customer_stats.rb, поэтому команда отката будет rake db:migrate:down VERSION=20140716084539


6

Чтобы откатить все миграции до определенной версии (например 20181002222222), используйте:

rake db:migrate VERSION=20181002222222

(Обратите внимание, что это использует db:migrate- не так, db:migrate:downкак в других ответах на этот вопрос.)

Предполагая, что указанная версия миграции старше текущей версии, это откатит все миграции до указанной версии, но не включая ее.

Например, если rake db:migrate:statusизначально отображается:

  (... some older migrations ...)
  up      20181001002039  Some migration description
  up      20181002222222  Some migration description
  up      20181003171932  Some migration description
  up      20181004211151  Some migration description
  up      20181005151403  Some migration description

Бег:

rake db:migrate VERSION=20181002222222

Приведет к:

  (... some older migrations ...)
  up      20181001002039  Some migration description
  up      20181002222222  Some migration description
  down    20181003171932  Some migration description
  down    20181004211151  Some migration description
  down    20181005151403  Some migration description

Ссылка: https://makandracards.com/makandra/845-migrate-or-revert-only-some-migrations


4

Из руководства по Rails

Возврат предыдущих миграций

Вы можете использовать возможность Active Record для отката миграций, используя revertметод:

require_relative '20100905201547_create_blocks'

class FixupCreateBlock < ActiveRecord::Migration
  def change
    revert CreateBlock

    create_table(:apples) do |t|
      t.string :variety
    end
  end
end

revertМетод также принимает блок инструкций для заднего хода. Это может быть полезно для возврата выбранных частей предыдущих миграций. Например, давайте представим, что CreateBlock зафиксирован, и позже было решено, что будет лучше использовать проверки Active Record вместо ограничения CHECK для проверки почтового индекса.

    class DontUseConstraintForZipcodeValidationMigration < ActiveRecord::Migration
      def change
        revert do
          # copy-pasted code from CreateBlock
          reversible do |dir|
            dir.up do
              # add a CHECK constraint
              execute <<-SQL
                ALTER TABLE distributors
                  ADD CONSTRAINT zipchk
                    CHECK (char_length(zipcode) = 5);
              SQL
            end
            dir.down do
              execute <<-SQL
                ALTER TABLE distributors
                  DROP CONSTRAINT zipchk
              SQL
            end
          end

          # The rest of the migration was ok
        end
      end
    end

Та же самая миграция также могла быть написана без использования revert, но для этого потребовалось бы еще несколько шагов: изменение порядка create_table и reversible, замена create_table на drop_table и, наконец, замена up на down и наоборот. Это все позаботится о возвращении.


3

Миграции изменяют состояние базы данных с помощью команды

$ bundle exec rake db:migrate

Мы можем отменить один шаг миграции, используя

  $ bundle exec rake db:rollback

Чтобы вернуться к началу, мы можем использовать

  $ bundle exec rake db:migrate VERSION=0

Как вы можете догадаться, замена любого другого числа на 0 мигрирует к этому номеру версии, где номера версий происходят из списка последовательных миграций


2

Что ж, в rails 5 это довольно просто: rake db: migrate: status или rails db: migrate: status

Он был изменен, чтобы обрабатывать их одинаково. Затем просто выберите версию, которую вы хотите откатить, и затем запустите rake db: migrate VERSION = 2013424230423

Убедитесь, что ВЕРСИЯ - все заглавные буквы

Если у вас есть проблема с каким-либо шагом миграции или вы застряли в середине, просто перейдите к файлу миграции и закомментируйте строки, которые уже были перенесены.

надеюсь, это поможет


1
Подчеркиваю подсказку для команды rake db: migrate: status . , , Это здорово для обзора, чтобы увидеть текущее состояние выполнения файлов миграции.
Салон красоты

1

Если вы хотите выполнить откат и миграцию, вы можете запустить:

rake db:migrate:redo

Это так же, как:

rake db:rollback
rake db:migrate
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.