Esegui un singolo file di migrazione


267

C'è un modo semplice per eseguire una singola migrazione? Non voglio migrare a una determinata versione, voglio solo eseguirne una specifica.


È qualcosa che hai eseguito una volta come migrazione perché si rendeva necessaria, quindi risulta essere una query utile che potrebbe essere necessario eseguire più volte? forse dovresti rifattare il contenuto della migrazione in un modello o in un altro oggetto, quindi avere il riferimento di migrazione in quella nuova posizione. Quindi puoi semplicemente eseguire il nuovo oggetto a tuo danno invocando ruby ​​sulla riga di comando.
Nathan Feger,

Risposte:


240

Puoi semplicemente eseguire il codice direttamente dal file ruby:

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

Nota: potrebbero essere necessarie versioni più recenti di binari AddFoos.new.upanziché AddFoos.up.

Un modo alternativo (senza IRB) che si basa sul fatto che richiedono restituisce una matrice di nomi di classe:

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

Nota che se lo fai, probabilmente non aggiornerà la schema_migrationstabella, ma sembra che sia quello che vuoi comunque.


59
A volte è necessario un './' davanti al percorso richiesto e sicuramente non aggiorna lo schema_migrations.
Beardo,

14
Prima di poter richiamare ho dovuto creare un'istanza dell'oggetto di migrazione. ad es.AddFoos.new.up
Bentleyo,

15
Quindi, per riassumere per Rails 3.2: require "./db/migrate/db/migrate/20090408054532_add_foos.rb"quindiAddFoos.new.up
trisweb l'

50
Se la tua migrazione utilizza changeinvece di upe down, dovrai eseguireAddFoos.new.migrate(:up)
Don Werve il

6
In Rails 4, puoi chiamareAddFoos.new.change
lfender6445 il

429

Supponendo che una versione abbastanza recente di Rails sia sempre possibile eseguire:

rake db:migrate:up VERSION=20090408054532

Dove versione è la data / ora nel nome file della migrazione.

Modifica: ad un certo punto negli ultimi 8 anni (non sono sicuro di quale versione) Rails ha aggiunto controlli che ne impediscono l'esecuzione se è già stata eseguita. Ciò è indicato da una voce nella schema_migrationstabella. Per rieseguirlo, esegui semplicemente rake db:migrate:redo VERSION=20090408054532invece.


124
In realtà il comando è rake db: migrate: redo VERSIONE = my_version
Chirag Patel

2
@Chirag Patel: Questo è esattamente quello che stavo cercando! Grazie!
Abele,

23
redo esegue successivamente il metodo down della migrazione data e il metodo up. up esegue solo il metodo up e penso che sia esattamente quello che vuole la persona che chiede.
Sven Koschnicke,

7
'up' sembra non funzionare se la versione dello schema del database è successiva alla migrazione in questione, il che può accadere ad esempio quando si uniscono le modifiche di un'altra persona.
Matt Connolly,

3
Grazie, l'ho usato per rake db:migrate:down VERSION=XXX
dire

107

Se vuoi eseguire una migrazione specifica , fallo

$ rake db:migrate:up VERSION=20080906120000

Se si desidera eseguire più migrazioni , farlo

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

Se vuoi eseguire una singola migrazione più volte, fallo

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

(puoi trovare il numero di versione nel nome file della tua migrazione)


Modifica: puoi anche semplicemente rinominare il tuo file di migrazione, ad esempio:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

Quindi migrare normalmente, questo tratterà la migrazione come nuova (utile se si desidera migrare su un ambiente remoto (come la gestione temporanea) su cui si ha meno controllo.

Modifica 2 : è anche possibile aggiungere una nuke alla voce di migrazione nel database. Per esempio:

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

rake db:migrateeseguirà quindi nuovamente il upmetodo delle migrazioni sfocate.


Sia "up" che "redo" non hanno funzionato per me, ma eliminare la riga in schema_migrations è stato perfetto.
cesoide,

27

Se hai implementato un changemetodo come questo:

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

È possibile creare un'istanza della migrazione ed eseguirla migrate(:up)o migrate(:down)su un'istanza, in questo modo:

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

1
Questo vale anche se stai usando upe down.
prendi il

17

Questi sono i passaggi per eseguire nuovamente questo file di migrazione "20150927161307_create_users.rb"

  1. Esegui la modalità console. (binari c)
  2. Copia e incolla la classe che si trova in quel file sulla 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. Crea un'istanza della classe CreateUsers:c1 = CreateUsers.new

  4. Eseguire il metodo changedi tale istanza:c1.change

basta richiedere il file con la classe, ad esempio nella console: require "./db/migrate/20150927161307_create_users.rb"invece di copiare e incollare. È quindi possibile eseguire la classe allo stesso modo creando un'istanza e chiamando il metodo definito nella classe CreateUsers.new.change.
VinnyQ77,

13

A partire da rails 5te puoi anche usare railsinvece dirake

Rotaie 3 - 4

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

Rotaie 5

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

# or

rails db:migrate:up VERSION=20160920130051

1
indovina anche di cosa hai bisognorails db:migrate VERSION=20160920130051
frenesim

12

Se hai problemi con i percorsi che puoi usare

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

6

Metodo 1:

rake db:migrate:up VERSION=20080906120000

Metodo 2:

In Rails Console 1. Copia incolla la classe di migrazione nella console (ad esempio add_name_to_user.rb) 2. Quindi nella console, digita quanto segue

Sharding.run_on_all_shards{AddNameToUser.up}

È fatta!!


5

Si noti che invece di script/runner, potrebbe essere necessario utilizzare rails runnersu nuovi ambienti rotaie.


3

Se vuoi eseguirlo dalla console, questo è quello che stai cercando:

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

Ho provato le altre risposte, ma richiedendo senza Rails.rootdi me non ha funzionato.

Inoltre, .migrate(:up)parte impone di rieseguire la migrazione indipendentemente dal fatto che sia già stata eseguita o meno. Questo è utile per quando hai già eseguito una migrazione, l'hai annullata un po 'scherzando con il db e vuoi una soluzione rapida per riaverla.


1

Sembra almeno nell'ultima versione di Rails (5.2 al momento in cui scrivo) c'è un altro modo per filtrare le migrazioni in esecuzione. È possibile passare un filtro in una SCOPEvariabile d'ambiente che verrebbe quindi utilizzato per selezionare i file di migrazione.

Supponendo di avere due file di migrazione 1_add_foos.rbe in 2_add_foos.run_this_one.rbesecuzione

SCOPE=run_this_one rails db:migrate:up

selezionerà ed eseguirà solo 2_add_foos.run_this_one.rb. Tenere presente che verranno eseguiti tutti i file di migrazione corrispondenti all'ambito.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.