Ejecute un solo archivo de migración


267

¿Hay una manera fácil de ejecutar una única migración? No quiero migrar a una versión determinada, solo quiero ejecutar una específica.


¿Es esto algo que ejecutó una vez como migración porque resultó ser necesario, y luego resultó ser una consulta útil que podría necesitar ejecutarse varias veces? quizás debería refactorizar el contenido de la migración a un modelo u otro objeto, luego hacer que la migración haga referencia a esa nueva ubicación. Luego, simplemente puede ejecutar el nuevo objeto en su lesión invocando ruby ​​en la línea de comando.
Nathan Feger el

Respuestas:


240

Puede ejecutar el código directamente desde el archivo ruby:

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

Nota: las versiones más nuevas de rieles pueden requerir en AddFoos.new.uplugar de AddFoos.up.

Una forma alternativa (sin IRB) que se basa en el hecho de que require devuelve una matriz de nombres de clase:

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

Tenga en cuenta que si hace esto, probablemente no actualizará la schema_migrationstabla, pero parece que eso es lo que quiere de todos modos.


59
A veces necesita un './' delante de la ruta requerida, y definitivamente no actualiza el schema_migrations.
Beardo

14
Tuve que crear una instancia del objeto de migración antes de poder llamar. Por ejemploAddFoos.new.up
Bentleyo

15
Entonces, para resumir para Rails 3.2: require "./db/migrate/db/migrate/20090408054532_add_foos.rb"entoncesAddFoos.new.up
trisweb

50
Si su migración usa en changelugar de upy down, deberá ejecutarAddFoos.new.migrate(:up)
Don Werve

66
En los rieles 4, puede llamarAddFoos.new.change
lfender6445

429

Suponiendo una versión bastante reciente de Rails, siempre puede ejecutar:

rake db:migrate:up VERSION=20090408054532

Donde versión es la marca de tiempo en el nombre de archivo de la migración.

Editar: en algún momento durante los últimos 8 años (no estoy seguro de qué versión) Rails agregó controles que impiden que esto se ejecute si ya se ha ejecutado. Esto se indica mediante una entrada en la schema_migrationstabla. Para volver a ejecutarlo, simplemente ejecute en su rake db:migrate:redo VERSION=20090408054532lugar.


124
En realidad, el comando es rake db: migrate: redo VERSION = my_version
Chirag Patel

2
@Chirag Patel: ¡Eso es exactamente lo que estaba buscando! ¡Gracias!
Abel

23
redo ejecuta el método down de la migración dada y el método up después de eso. up solo ejecuta el método up, y creo que eso es exactamente lo que quiere la persona que pregunta.
Sven Koschnicke

77
'up' parece no ejecutarse si la versión del esquema de la base de datos es posterior a la migración en cuestión, lo que puede suceder al fusionar los cambios de otra persona, por ejemplo.
Matt Connolly

3
Gracias, usé esto para abajo conrake db:migrate:down VERSION=XXX
Nitrodist

107

Si desea ejecutar una migración específica , haga

$ rake db:migrate:up VERSION=20080906120000

Si desea ejecutar migraciones varias veces , haga

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

Si desea ejecutar una sola migración varias veces, haga

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

(puede encontrar el número de versión en el nombre de archivo de su migración)


Editar: También puede simplemente cambiar el nombre de su archivo de migración, por ejemplo:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

Luego migre normalmente, esto tratará la migración como una nueva (útil si desea migrar en un entorno remoto (como la puesta en escena) en el que tiene menos control.

Edición 2 : también puede eliminar la entrada de migración en la base de datos. P.ej:

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

rake db:migrateluego volverá a ejecutar el upmétodo de las migraciones nucleadas.


Tanto "arriba" como "rehacer" no funcionaron para mí, pero eliminar la fila en schema_migrations fue perfecto.
cesoid

27

Si ha implementado un changemétodo como este:

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

Puede crear una instancia de la migración y ejecutarla migrate(:up)o migrate(:down)en una instancia, como esta:

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

1
Esto también se aplica incluso si está utilizando upy down.
gak

17

Estos son los pasos para volver a ejecutar este archivo de migración "20150927161307_create_users.rb"

  1. Ejecute el modo de consola. (rieles c)
  2. Copie y pegue la clase que está en ese archivo en la consola.

    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 una instancia de la clase CreateUsers:c1 = CreateUsers.new

  4. Ejecute el método changede esa instancia:c1.change

solo requiere el archivo con la clase, por ejemplo, en la consola: en require "./db/migrate/20150927161307_create_users.rb"lugar de copiar y pegar. Luego puede ejecutar la clase de la misma manera instanciando y llamando al método definido en la clase CreateUsers.new.change.
VinnyQ77

13

A partir de rails 5usted también puede usar en railslugar derake

Rieles 3 - 4

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

Carriles 5

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

# or

rails db:migrate:up VERSION=20160920130051

1
también adivina lo que necesitasrails db:migrate VERSION=20160920130051
frenesim 03 de

12

Si tienes problemas con los caminos, puedes usar

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

6

Método 1 :

rake db:migrate:up VERSION=20080906120000

Método 2:

En la consola de Rails 1. Copie y pegue la clase de migración en la consola (digamos add_name_to_user.rb) 2. Luego, en la consola, escriba lo siguiente

Sharding.run_on_all_shards{AddNameToUser.up}

¡¡Se hace!!


5

Tenga en cuenta que, en lugar de hacerlo script/runner, es posible que deba usarlo rails runneren entornos de rieles nuevos.


3

Si desea ejecutarlo desde la consola, esto es lo que está buscando:

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

Intenté las otras respuestas, pero requerirlo sin Rails.rootque me funcionase.

Además, .migrate(:up)parte obliga a que la migración se vuelva a ejecutar independientemente de si ya se ha ejecutado o no. Esto es útil para cuando ya ejecutó una migración, la ha deshecho un poco jugando con la base de datos y desea una solución rápida para volverla a ejecutar.


1

Parece que al menos en la última versión de Rails (5.2 en el momento de la escritura) hay una forma más de filtrar las migraciones que se ejecutan. Se puede pasar un filtro en una SCOPEvariable de entorno que luego se usaría para seleccionar archivos de migración.

Suponiendo que tiene dos archivos de migración 1_add_foos.rby en 2_add_foos.run_this_one.rbejecución

SCOPE=run_this_one rails db:migrate:up

seleccionará y solo se ejecutará 2_add_foos.run_this_one.rb. Tenga en cuenta que se ejecutarán todos los archivos de migración que coincidan con el alcance.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.