Запустить один файл миграции


267

Есть ли простой способ запустить одну миграцию? Я не хочу переходить на определенную версию, я просто хочу запустить определенную.


Является ли это чем-то, что вы запускали один раз как миграцию, потому что это оказалось необходимым, а затем оказывается полезным запросом, который может потребоваться выполнить несколько раз? возможно, вам следует провести рефакторинг содержимого миграции в модель или другой объект, а затем указать ссылку на это новое местоположение. Затем вы можете просто выполнить новый объект по вашему усмотрению, вызвав ruby ​​в командной строке.
Натан Фегер

Ответы:


240

Вы можете просто запустить код прямо из файла ruby:

rails console
>> require "db/migrate/20090408054532_add_foos.rb"
>> AddFoos.up

Примечание: более новые версии рельсов могут потребовать, AddFoos.new.upа не AddFoos.up.

Альтернативный способ (без IRB), основанный на том факте, что require возвращает массив имен классов:

script/runner 'require("db/migrate/20090408054532_add_foos.rb").first.constantize.up'

Обратите внимание, что если вы сделаете это, он, вероятно, не обновит schema_migrationsтаблицу, но, похоже, это то, что вам нужно в любом случае.


59
Иногда вам нужен «./» перед обязательным путем, и он определенно не обновляет schema_migrations.
Бердо

14
Мне пришлось создать экземпляр объекта миграции, прежде чем я смог вызвать. напримерAddFoos.new.up
Bentleyo

15
Итак, require "./db/migrate/db/migrate/20090408054532_add_foos.rb"AddFoos.new.up
подведем

50
Если ваша миграция использует changeвместо upи down, вам нужно будет запуститьAddFoos.new.migrate(:up)
Дон Верв

6
В рельсах 4 вы можете позвонитьAddFoos.new.change
lfender6445

429

Предполагая довольно свежую версию Rails, вы всегда можете запустить:

rake db:migrate:up VERSION=20090408054532

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

Изменить: В какой-то момент за последние 8 лет (я не уверен, какая версия) Rails добавил проверки, которые не позволяют запускаться, если он уже был запущен. На это указывает запись в schema_migrationsтаблице. Чтобы перезапустить его, просто выполните rake db:migrate:redo VERSION=20090408054532вместо этого.


124
На самом деле это команда rake db: migrate: redo VERSION = my_version
Chirag Patel,

2
@ Чираг Патель: Это именно то, что я искал! Спасибо!
Авель

23
redo запускает метод down данной миграции и метод up после этого. up работает только по методу up, и я думаю, что это именно то, чего хочет спрашивающий.
Свен Кошничке

7
«up» не запускается, если версия схемы базы данных более поздняя, ​​чем рассматриваемая миграция, что может произойти, например, при объединении изменений другого человека.
Мэтт Коннолли

3
Спасибо, я использовал это дляrake db:migrate:down VERSION=XXX
Nitrodist

107

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

$ rake db:migrate:up VERSION=20080906120000

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

# use the STEP parameter if you need to go more than one version back
$ rake db:migrate:redo STEP=3

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

# this is super useful
$ rake db:migrate:redo VERSION=20080906120000

(номер версии можно найти в имени файла вашей миграции)


Изменить: Вы также можете просто переименовать файл миграции, например:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

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

Редактировать 2 : Вы также можете просто сбросить запись миграции в базе данных. Например:

rails_c> q = "delete from schema_migrations where version = '20151013131830'"
rails_c> ActiveRecord::Base.connection.execute(q)

rake db:migrateзатем повторно запустит upметод ядерных миграций.


И «вверх», и «повтор» у меня не сработали, но удаление строки в schema_migrations было идеальным.
cesoid

27

Если вы реализовали такой changeметод:

class AddPartNumberToProducts < ActiveRecord::Migration
  def change
    add_column :products, :part_number, :string
  end
end

Вы можете создать экземпляр миграции и запустить migrate(:up)или migrate(:down)на экземпляре, например так:

$ rails console
>> require "db/migrate/20090408054532_add_part_number_to_products.rb"
>> AddPartNumberToProducts.new.migrate(:down)

1
Это также относится, даже если вы используете upи down.
Гак

17

Это шаги для повторного запуска этого файла миграции "20150927161307_create_users.rb"

  1. Запустите консольный режим. (рельсы с)
  2. Скопируйте и вставьте класс, который находится в этом файле, в консоль.

    class CreateUsers < ActiveRecord::Migration
      def change
        create_table :users do |t|
          t.string :name
          t.string :email
          t.timestamps null: false   end
        end
      end
    end
  3. Создайте экземпляр класса CreateUsers:c1 = CreateUsers.new

  4. Выполните метод changeэтого экземпляра:c1.change

просто требуется файл с классом, например, в консоли: require "./db/migrate/20150927161307_create_users.rb"вместо копирования и вставки. Затем вы можете запустить класс таким же образом, создав экземпляр и вызвав метод, определенный в классе CreateUsers.new.change.
VinnyQ77

13

Как rails 5вы можете также использовать railsвместоrake

Рельсы 3 - 4

# < rails-5.0
rake db:migrate:up VERSION=20160920130051

Рельсы 5

# >= rails-5.0
rake db:migrate:up VERSION=20160920130051

# or

rails db:migrate:up VERSION=20160920130051

1
это также угадать, что вам нужно сrails db:migrate VERSION=20160920130051
Frenesim


6

Способ 1:

rake db:migrate:up VERSION=20080906120000

Способ 2:

В Rails Console 1. Скопируйте и вставьте класс миграции в консоль (скажем, add_name_to_user.rb). 2. Затем в консоли введите следующее

Sharding.run_on_all_shards{AddNameToUser.up}

Сделано!!


5

Обратите внимание, что вместо этого script/runnerвам, возможно, придется использовать rails runnerновые рельсы.


3

Если вы хотите запустить его из консоли, это то, что вы ищете:

$ rails console
irb(main)> require "#{Rails.root.to_s}/db/migrate/XXXXX_my_migration.rb"
irb(main)> AddFoo.migrate(:up)

Я попробовал другие ответы, но требование без Rails.rootменя не сработало.

Кроме того, .migrate(:up)part принудительно перезапускает миграцию независимо от того, запущена она или нет. Это полезно, когда вы уже запустили миграцию, отмените ее, возитесь с базой данных и хотите быстрое решение, чтобы снова ее запустить.


1

Похоже, по крайней мере, в последней версии Rails (5.2 на момент написания статьи) есть еще один способ фильтрации выполняемых миграций. Можно передать фильтр в SCOPEпеременную окружения, которая затем будет использоваться для выбора файлов миграции.

Предполагая, что у вас есть два файла миграции 1_add_foos.rbи 2_add_foos.run_this_one.rbработает

SCOPE=run_this_one rails db:migrate:up

будет выбирать и запускать только 2_add_foos.run_this_one.rb. Помните, что все файлы миграции, соответствующие области действия, будут запущены.

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