Сделайте всего одну миграцию

94

Я пытаюсь выполнить только одну миграцию из целой кучи в моем приложении rails. Как я могу это сделать? Я не хочу запускать какие-либо миграции до или после нее. Спасибо.

Анон
источник
1
Это была бы удобная функция rails: добавьте STEP=nаргумент в db:migrate(где n- количество запускаемых миграций, как и для db:rollback) - тогда вы можете сделать rake db:migrate STEP=1или rake db:migrate STEP=2и т. Д.
user664833

Ответы:

164

rake db:migrate:redo VERSION=xxxxxxx, но это запустит, downа затем upшаг. Вы можете сделать это вместе с временным комментарием шага вниз.

Райан Бигг
источник
Хм, blog.stonean.com/2007/12/18/rake-dbmigrateredo , :: redo, похоже, не принимает аргумент ВЕРСИЯ.
Терри Джи Лорбер,
3
@pedrorolo: Это не устарело. У этой задачи нет описания, поэтому она не будет отображаться в rake -T.
Райан Бигг,
1
@pedrorolo: db:test:prepareтоже не отображается в этом списке. Боже, я опаздываю на вечеринку.
mraaroncruz
9
Чтобы расширить то, что говорит Райан, если таблица была удалена из базы данных вне Rails, она rake db:migrate:up VERSION=my_versionможет ничего не сделать , потому что таблица schema_migrations по-прежнему говорит, что она была запущена. В той же ситуации rake db:migrate:redo VERSION=my_versionможет произойти сбой, поскольку он не может отбросить таблицу. В этом случае, downвременно закомментируйте метод в переносе и запустите его повторноrake db:migrate:redo...
Лев
3
И чтобы расширить то, что говорит @Leo, если миграция определяется с помощью def change, измените его на def self.up в дополнение к вышеупомянутому.
valk
70
rake db:migrate:up VERSION=1234567890

аналогично rake db:migrate:downдля конкретной миграции вниз. Вы можете получить список доступных рейк-заданий с помощью rake -T.

Shadwell
источник
4
VERSIONУпомянуто здесь целое значение в начале каждого из файлов миграции (это просто метка времени, когда она была создана). Например, VERSION=20150720023630.
aaron-coding
3
Версии отображаются красиво с rake db: migrate: status
jpgeek
Примечательно, что VERSIONэто просто переменная среды, поэтому она может стоять первой в команде или даже предшествовать команде:VERSION=1234567890 rake db:migrate:up
Джошуа Пинтер
25

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

>> require 'db/migrate/your_migrations.rb'
=> ["YourMigrations"]
>> YourMigrations.up
=> etc... as the migration runs
>> YourMigration.down

Более полезно это было бы поместить в задачу грабли и т. Д.


источник
6
Это сработало потрясающе. Вы также можете просто скопировать и вставить код из миграции в консоль, чтобы определить класс (и это позволяет при необходимости выполнять ручные манипуляции, например, если вы только что сделали ошибку на Dev). Если вы определили обратимую миграцию с помощью change, запускайте YourMigrations.migrate(:up)вместо :down
нее
1
вам, возможно, придетсяrequire "#{Rails.root}/db/migrate/your_migrations.rb"
s2t2
16

rake db:migrate:up VERSION=version_no

Будет перенесен (добавлен) конкретный сценарий миграции

rake db:migrate:down VERSION=version_no

Удалит конкретный сценарий миграции

решма
источник
11
rake db:migrate VERSION=20098252345

попробуйте.

JP Silvashy
источник
8
Я думаю, это запустит любые миграции до указанной вами.
Кен Лю
1
close, но это также запускает любые миграции перед конкретной миграцией.
Anon
6
Я не думаю, что вы должны / хотите запускать только одну миграцию без учета предыдущих. Миграция - это представление структуры базы данных, связанной с кодом в данный момент времени, и, следовательно, миграции до нее необходимы. Если вы хотите запустить только одну миграцию, скорее всего, вы не написали правильные операции вверх / вниз, чтобы сохранить функциональность миграции ... это плохая привычка записывать только свои миграции вверх.
JP Silvashy
1
Примечательно: VERSIONэто просто переменная среды, поэтому она может стоять первой в команде или даже предшествовать команде:VERSION=20098252345 rake db:migrate
Джошуа Пинтер
4
rake db:migrate:redo version='xxxx'   

Не забудьте поставить кавычки вокруг xxxx, xxxx - это метка времени (или идентификатор миграции) для вашей миграции.

Вы можете проверить временные метки (идентификатор миграции) для предыдущих миграций, которые вы сделали, используя

rake db:migrate:status    
гексинпетер
источник
3

Расширение ответа на корч выше, requireу меня не сработало, но сработало load. Чтобы быть конкретным, для файла миграции:

    class ChangeMinQuantityToRaces < ActiveRecord::Migration
      def change
        change_column :races, :min_quantity, :integer, :default => 0
      end
    end

в консоли набрав

    > load 'db/migrate/30130925110821_change_min_quantity_to_races.rb'
    > ChangeMinQuantityToRaces.new.change

работал у меня.

    > Race.new.min_quantity # => 0 

Это было для Ruby 1.9.3p484 (2013-11-22, ревизия 43786) [x86_64-linux] и Rails 3.2.13.

bhfailor
источник
2

Добавляю к этому мои 2 ¢, потому что я столкнулся с той же проблемой:

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

rails dbconsole -p devdb=# delete from public.schema_migrations where version = '20150105181157';

И rails «забудут», что он выполнил миграцию для 20150105181157. Теперь, когда вы запустите db: migrate, он снова запустит его.

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

Кен Саймон
источник
1

Должен быть способ запустить класс миграции через консоль. Кажется, я не могу сделать код миграции узнаваемым.

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

rake db:migrate VERSION=##########

Скопируйте и вставьте свой код при миграции в скрипт / консоль?

Терри Дж. Лорбер
источник
0

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

Это 100% хакерство, и я бы определенно не рекомендовал делать это в продакшене, но это поможет:

  1. Переместите миграцию, которую вы хотите повторно запустить из каталога, во временное место
  2. Создайте еще одну миграцию с тем же именем
  3. Скопируйте / вставьте исходный код миграции во вновь созданный файл миграции
  4. Запустите новую миграцию
  5. Удалите вновь созданный файл миграции
  6. Измените миграции схемы, чтобы удалить самое последнее значение
  7. Восстановите старый файл миграции
Грег Бласс
источник