Execute um único arquivo de migração


267

Existe uma maneira fácil de executar uma única migração? Não quero migrar para uma determinada versão, apenas quero executar uma versão específica.


Isso é algo que você executou uma vez como migração porque era necessário e, em seguida, acaba sendo uma consulta útil que pode precisar ser executada várias vezes? talvez você deva refatorar o conteúdo da migração para um modelo ou outro objeto e faça com que a migração faça referência a esse novo local. Então você pode simplesmente executar o novo objeto quando desejar, chamando ruby ​​na linha de comando.
Nathan Feger

Respostas:


240

Você pode simplesmente executar o código diretamente do arquivo ruby:

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

Nota: as versões mais recentes dos trilhos podem exigir, em AddFoos.new.upvez deAddFoos.up .

Uma maneira alternativa (sem IRB) que depende do fato de exigir retorna uma matriz de nomes de classes:

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

Observe que, se você fizer isso, provavelmente não atualizará a schema_migrationstabela, mas parece que é isso que você deseja.


59
Às vezes, você precisa de um './' na frente do caminho de solicitação e, definitivamente, não atualiza as schema_migrations.
Beardo

14
Eu tive que criar uma instância do objeto de migração antes de poder acessar. por exemploAddFoos.new.up
Bentleyo 30/10/12

15
Então, para resumir para Rails 3.2: require "./db/migrate/db/migrate/20090408054532_add_foos.rb"entãoAddFoos.new.up
trisweb

50
Se a migração usa changeem vez de upe down, você vai precisar executarAddFoos.new.migrate(:up)
Don Werve

6
No Rails 4, você pode chamarAddFoos.new.change
lfender6445

429

Supondo uma versão bastante recente do Rails, você sempre pode executar:

rake db:migrate:up VERSION=20090408054532

Onde version é o registro de data e hora no nome do arquivo da migração.

Edit: Em algum momento nos últimos 8 anos (não sei qual versão), o Rails adicionou verificações que impedem a execução, se já tiver sido executada. Isso é indicado por uma entrada na schema_migrationstabela. Para executá-lo novamente, basta executar rake db:migrate:redo VERSION=20090408054532.


124
Na verdade, o comando é rake db: migre: refazer VERSÃO = my_version
Chirag Patel

2
@Chirag Patel: Isso é exatamente o que eu estava procurando! Obrigado!
Abel

23
refazer executa o método down da migração fornecida e o método up depois disso. up executa apenas o método up, e acho que é exatamente isso que a pessoa que deseja perguntar.
Sven Koschnicke

7
'up' parece não ser executado se a versão do esquema do banco de dados for posterior à migração em questão, o que pode ocorrer ao mesclar as alterações de outra pessoa, por exemplo.
Matt Connolly

3
Obrigado, eu usei isso para baixo comrake db:migrate:down VERSION=XXX
Nitrodist

107

Se você deseja executar uma migração específica , faça

$ rake db:migrate:up VERSION=20080906120000

Se você deseja executar migrações várias vezes , faça

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

Se você deseja executar uma única migração várias vezes, faça

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

(você pode encontrar o número da versão no nome do arquivo da sua migração)


Editar: Você também pode simplesmente renomear seu arquivo de migração, por exemplo:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

Em seguida, migre normalmente, isso tratará a migração como uma nova (útil se você desejar migrar para um ambiente remoto (como armazenamento temporário) no qual você tem menos controle.

Editar 2 : você também pode apenas adicionar a entrada de migração no banco de dados. Por exemplo:

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

rake db:migrateexecutará novamente o upmétodo das migrações com armas nucleares.


"Up" e "redo" não funcionaram para mim, mas a exclusão da linha em schema_migrations foi perfeita.
cesoid

27

Se você implementou um changemétodo como este:

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

Você pode criar uma instância da migração e executar migrate(:up)ou migrate(:down)em uma instância, assim:

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

1
Isso também se aplica mesmo se você estiver usando upe down.
gak

17

Estas são as etapas para executar novamente este arquivo de migração "20150927161307_create_users.rb"

  1. Execute o modo do console. (trilhos c)
  2. Copie e cole a classe que está nesse arquivo no console.

    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. Crie uma instância da classe CreateUsers:c1 = CreateUsers.new

  4. Execute o método changedessa instância:c1.change

apenas exija o arquivo com a classe, por exemplo, no console: em require "./db/migrate/20150927161307_create_users.rb"vez de copiar e colar. Você pode executar a classe da mesma maneira instanciando e chamando o método definido na classe CreateUsers.new.change.
VinnyQ77 15/02

13

Como rails 5você também pode usar em railsvez derake

Trilhos 3 - 4

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

Trilhos 5

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

# or

rails db:migrate:up VERSION=20160920130051

1
ele também adivinha o que você precisa comrails db:migrate VERSION=20160920130051
frenesim 3/11/16

12

Se você está tendo problemas com os caminhos, pode usar

require Rails.root + 'db/migrate/20090408054532_add_foos.rb'

6

Método 1 :

rake db:migrate:up VERSION=20080906120000

Método 2:

No console do Rails 1. Copie e cole a classe de migração no console (por exemplo, add_name_to_user.rb) 2. Em seguida, no console, digite o seguinte

Sharding.run_on_all_shards{AddNameToUser.up}

Está feito!!


5

Observe que, em vez de script/runner, você pode precisar usar rails runnerem novos ambientes de trilhos.


3

Se você deseja executá-lo no console, é isso que você está procurando:

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

Eu tentei as outras respostas, mas exigir sem Rails.rootnão funcionou para mim.

Além disso, .migrate(:up)parte força a migração a ser executada novamente, independentemente de já ter sido executada ou não. Isso é útil para quando você já executou uma migração, meio que a desfez ao mexer com o banco de dados e deseja uma solução rápida para recuperá-la.


1

Parece que, pelo menos na versão mais recente do Rails (5.2 no momento da redação), há mais uma maneira de filtrar as migrações sendo executadas. Pode-se passar um filtro em uma SCOPEvariável de ambiente que seria usada para selecionar arquivos de migração.

Supondo que você tenha dois arquivos de migração 1_add_foos.rbe 2_add_foos.run_this_one.rbexecutando

SCOPE=run_this_one rails db:migrate:up

irá selecionar e executar apenas 2_add_foos.run_this_one.rb. Lembre-se de que todos os arquivos de migração correspondentes ao escopo serão executados.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.