Jalankan satu file migrasi


267

Apakah ada cara mudah untuk menjalankan satu migrasi? Saya tidak ingin bermigrasi ke versi tertentu, saya hanya ingin menjalankan yang spesifik.


Apakah ini sesuatu yang Anda jalankan sekali sebagai migrasi karena kebetulan diperlukan, kemudian ternyata menjadi kueri yang berguna yang mungkin perlu dijalankan beberapa kali? mungkin Anda harus memperbaiki isi migrasi menjadi model atau objek lain, lalu minta referensi migrasi ke lokasi baru. Kemudian Anda bisa mengeksekusi objek baru di lesi Anda dengan memanggil ruby ​​pada baris perintah.
Nathan Feger

Jawaban:


240

Anda bisa menjalankan kode langsung dari file ruby:

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

Catatan: versi rel yang lebih baru mungkin membutuhkan AddFoos.new.updaripada AddFoos.up.

Cara alternatif (tanpa IRB) yang bergantung pada fakta yang membutuhkan pengembalian array nama kelas:

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

Perhatikan bahwa jika Anda melakukan ini, itu mungkin tidak akan memperbarui schema_migrationstabel, tetapi sepertinya itulah yang Anda inginkan.


59
Terkadang Anda memerlukan './' di depan jalur yang diperlukan, dan itu pasti tidak memperbarui schema_migrations.
Beardo

14
Saya harus membuat instance objek migrasi sebelum saya bisa menelepon. egAddFoos.new.up
Bentleyo

15
Jadi, jumlah untuk Rails 3.2: require "./db/migrate/db/migrate/20090408054532_add_foos.rb"thenAddFoos.new.up
trisweb

50
Jika migrasi Anda menggunakan changealih-alih updan down, Anda harus menjalankanAddFoos.new.migrate(:up)
Don Werve

6
Di rails 4, Anda bisa meneleponAddFoos.new.change
lfender6445

429

Dengan asumsi Rails versi terbaru Anda selalu dapat menjalankan:

rake db:migrate:up VERSION=20090408054532

Di mana versi adalah cap waktu dalam nama file migrasi.

Sunting: Di beberapa titik selama 8 tahun terakhir (saya tidak yakin versi apa) Rail menambahkan cek yang mencegah ini berjalan jika sudah dijalankan. Ini ditunjukkan oleh entri dalam schema_migrationstabel. Untuk menjalankannya kembali, jalankan rake db:migrate:redo VERSION=20090408054532saja.


124
Sebenarnya perintahnya adalah rake db: migrate: redo VERSION = my_version
Chirag Patel

2
@Chirag Patel: Itulah tepatnya yang saya cari! Terima kasih!
Abel

23
redo menjalankan metode down dari migrasi yang diberikan dan metode naik setelah itu. up hanya menjalankan metode-up, dan saya pikir itulah yang diinginkan orang yang meminta.
Sven Koschnicke

7
'naik' tampaknya tidak berjalan jika versi skema database lebih lambat dari migrasi yang dimaksud, yang dapat terjadi ketika menggabungkan perubahan orang lain, misalnya.
Matt Connolly

3
Terima kasih, saya menggunakan ini untuk turunrake db:migrate:down VERSION=XXX
Nitrodist

107

Jika Anda ingin menjalankan migrasi tertentu , lakukan

$ rake db:migrate:up VERSION=20080906120000

Jika Anda ingin menjalankan migrasi beberapa kali , lakukan

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

Jika Anda ingin menjalankan satu migrasi beberapa kali, lakukan

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

(Anda dapat menemukan nomor versi di nama file migrasi Anda)


Sunting: Anda juga dapat dengan mudah mengganti nama file migrasi Anda, Misalnya:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

Kemudian bermigrasi secara normal, ini akan memperlakukan migrasi sebagai yang baru (berguna jika Anda ingin bermigrasi di lingkungan yang jauh (seperti pementasan) di mana Anda memiliki kontrol lebih sedikit.

Sunting 2 : Anda juga bisa hanya mem-nuke entri migrasi dalam database. Misalnya:

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

rake db:migratekemudian akan menjalankan kembali upmetode migrasi nuked.


Baik "naik" dan "mengulang" tidak bekerja untuk saya, tetapi menghapus baris di schema_migrations sempurna.
cesoid

27

Jika Anda telah menerapkan changemetode seperti ini:

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

Anda dapat membuat instance migrasi dan menjalankan migrate(:up)atau migrate(:down)pada instance, seperti ini:

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

1
Ini juga berlaku bahkan jika Anda menggunakan updan down.
gak

17

Ini adalah langkah-langkah untuk menjalankan lagi file migrasi ini "20150927161307_create_users.rb"

  1. Jalankan mode konsol. (rel c)
  2. Salin dan lewati kelas yang ada di file itu ke konsol.

    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. Buat instance kelas CreateUsers:c1 = CreateUsers.new

  4. Jalankan metode changeinstance itu:c1.change

hanya membutuhkan file dengan kelas, misalnya di konsol: require "./db/migrate/20150927161307_create_users.rb"alih-alih menyalin & menempel. Anda kemudian dapat menjalankan kelas dengan cara yang sama dengan membuat instance dan memanggil metode yang didefinisikan dalam kelas CreateUsers.new.change.
VinnyQ77

13

Sampai rails 5Anda juga dapat menggunakan railsbukannyarake

Rel 3 - 4

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

Rel 5

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

# or

rails db:migrate:up VERSION=20160920130051

1
itu juga menebak apa yang Anda butuhkan denganrails db:migrate VERSION=20160920130051
frenesim

12

Jika Anda memiliki masalah dengan jalur yang bisa Anda gunakan

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

6

Metode 1:

rake db:migrate:up VERSION=20080906120000

Metode 2:

Di Rails Console 1. Salin tempelkan kelas migrasi di konsol (mis. Add_name_to_user.rb) 2. Kemudian di konsol, ketikkan yang berikut ini

Sharding.run_on_all_shards{AddNameToUser.up}

Sudah selesai !!


5

Harap perhatikan bahwa alih-alih script/runner, Anda mungkin harus menggunakan rails runnerpada lingkungan rel baru.


3

Jika Anda ingin menjalankannya dari konsol, inilah yang Anda cari:

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

Saya mencoba jawaban lain, tetapi membutuhkan tanpa Rails.roottidak berhasil untuk saya.

Selain itu, .migrate(:up)sebagian memaksa migrasi untuk menjalankan ulang terlepas dari apakah sudah berjalan atau belum. Ini berguna untuk ketika Anda sudah menjalankan migrasi, harus membatalkannya dengan bermain-main dengan db dan ingin solusi cepat untuk mendapatkannya kembali.


1

Sepertinya setidaknya dalam rilis Rails terbaru (5.2 pada saat penulisan) ada satu lagi cara memfilter migrasi yang sedang dijalankan. Seseorang dapat melewati filter dalam SCOPEvariabel lingkungan yang kemudian akan digunakan untuk memilih file migrasi.

Dengan asumsi Anda memiliki dua file migrasi 1_add_foos.rbdan 2_add_foos.run_this_one.rbberjalan

SCOPE=run_this_one rails db:migrate:up

akan memilih dan menjalankan saja 2_add_foos.run_this_one.rb. Perlu diingat bahwa semua file migrasi yang sesuai dengan cakupan akan dijalankan.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.