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.

nan
fonte
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.

Orion Edwards
fonte
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.

gtd
fonte
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.

Benjamin Crouzier
fonte
"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)
chibicode
fonte
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
rolph dzounga
fonte
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
Deepak Mahakale
fonte
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'
Dejan Cancarevic
fonte
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!!

ramya
fonte
5

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

viniciusnz
fonte
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.

Tasos Anesiadis
fonte
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.

szymek
fonte