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

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вместо этого.

GTD
источник
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)
chibicode
источник
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
12

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

require Rails.root + 'db/migrate/20090408054532_add_foos.rb'
Деян Канкаревич
источник
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новые рельсы.

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

szymek
источник