Chạy một tệp di chuyển


267

Có một cách dễ dàng để chạy một di chuyển? Tôi không muốn chuyển sang một phiên bản nhất định Tôi chỉ muốn chạy một phiên bản cụ thể.


Đây có phải là thứ mà bạn đã chạy một lần khi di chuyển vì nó cần thiết, sau đó hóa ra là một truy vấn hữu ích có thể cần phải chạy một số lần? có lẽ bạn nên cấu trúc lại nội dung di chuyển thành một mô hình hoặc đối tượng khác, sau đó có tham chiếu di chuyển vị trí mới đó. Sau đó, bạn có thể chỉ cần thực hiện đối tượng mới tại vị trí của mình bằng cách gọi ruby ​​trên dòng lệnh.
Nathan Feger

Câu trả lời:


240

Bạn chỉ có thể chạy mã trực tiếp từ tệp ruby:

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

Lưu ý: phiên bản mới hơn của đường ray có thể yêu cầu AddFoos.new.uphơn là AddFoos.up.

Một cách khác (không có IRB) dựa trên thực tế yêu cầu trả về một mảng các tên lớp:

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

Lưu ý rằng nếu bạn làm điều này, nó có thể sẽ không cập nhật schema_migrationsbảng, nhưng có vẻ như đó là những gì bạn muốn.


59
Đôi khi bạn cần một './' phía trước đường dẫn yêu cầu và nó chắc chắn không cập nhật lược đồ_migations.
Beardo

14
Tôi đã phải tạo một thể hiện của đối tượng di chuyển trước khi tôi có thể gọi lên. ví dụ:AddFoos.new.up
Bentleyo

15
Vì vậy, để tổng hợp cho Rails 3.2: require "./db/migrate/db/migrate/20090408054532_add_foos.rb"sau đóAddFoos.new.up
trisweb

50
Nếu di chuyển của bạn sử dụng changethay vì updown, bạn sẽ cần phải chạyAddFoos.new.migrate(:up)
Don Werve

6
Trong đường ray 4, bạn có thể gọiAddFoos.new.change
lfender6445

429

Giả sử phiên bản Rails khá gần đây bạn luôn có thể chạy:

rake db:migrate:up VERSION=20090408054532

Trong đó phiên bản là dấu thời gian trong tên tệp của di chuyển.

Chỉnh sửa: Tại một số thời điểm trong 8 năm qua (Tôi không chắc là phiên bản nào) Rails đã thêm các kiểm tra ngăn việc này chạy nếu nó đã được chạy. Điều này được chỉ định bởi một mục trong schema_migrationsbảng. Để chạy lại nó, chỉ cần thực hiện rake db:migrate:redo VERSION=20090408054532thay thế.


124
Trên thực tế, lệnh là rake db: di chuyển: làm lại VERSION = my_version
Chirag Patel

2
@Chirag Patel: Đó chính xác là những gì tôi đang tìm kiếm! Cảm ơn!
Abel

23
làm lại chạy phương thức xuống của di chuyển đã cho và phương thức lên sau đó. chỉ chạy phương thức lên, và tôi nghĩ đó là chính xác những gì người hỏi muốn.
Sven Koschnicke

7
'lên' dường như không chạy nếu phiên bản lược đồ cơ sở dữ liệu muộn hơn so với di chuyển trong câu hỏi, điều này có thể xảy ra khi hợp nhất các thay đổi của người khác, ví dụ.
Matt Connolly

3
Cảm ơn, tôi đã sử dụng cái này cho xuống vớirake db:migrate:down VERSION=XXX
Nitrodist

107

Nếu bạn muốn chạy một di chuyển cụ thể , hãy làm

$ rake db:migrate:up VERSION=20080906120000

Nếu bạn muốn chạy di chuyển nhiều lần , hãy làm

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

Nếu bạn muốn chạy một lần di chuyển nhiều lần, hãy làm

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

(bạn có thể tìm thấy số phiên bản trong tên tệp di chuyển của mình)


Chỉnh sửa: Bạn cũng có thể chỉ cần đổi tên tệp di chuyển của mình, vd:

20151013131830_my_migration.rb -> 20151013131831_my_migration.rb

Sau đó di chuyển bình thường, điều này sẽ coi việc di chuyển là một di chuyển mới (hữu ích nếu bạn muốn di chuyển trên một môi trường từ xa (chẳng hạn như dàn dựng) mà bạn có ít quyền kiểm soát hơn.

Chỉnh sửa 2 : Bạn cũng có thể chỉ cần nhập mục di chuyển trong cơ sở dữ liệu. Ví dụ:

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

rake db:migratesau đó sẽ chạy lại upphương thức di chuyển của nuked.


Cả "lên" và "làm lại" đều không hiệu quả với tôi, nhưng xóa hàng trong lược đồ_migations là hoàn hảo.
Caesoid

27

Nếu bạn đã thực hiện một changephương pháp như thế này:

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

Bạn có thể tạo một phiên bản di chuyển và chạy migrate(:up)hoặc migrate(:down)trên một cá thể, như thế này:

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

1
Điều này cũng áp dụng ngay cả khi bạn đang sử dụng updown.
gak

17

Đây là các bước để chạy lại tệp di chuyển này "20150927161307_create_users.rb"

  1. Chạy chế độ điều khiển. (đường ray c)
  2. Sao chép và qua lớp trong tệp đó vào bàn điều khiển.

    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. Tạo một thể hiện của lớp CreateUsers:c1 = CreateUsers.new

  4. Thực hiện phương thức changecủa trường hợp đó:c1.change

chỉ yêu cầu tệp với lớp, ví dụ trong bảng điều khiển: require "./db/migrate/20150927161307_create_users.rb"thay vì sao chép và dán. Sau đó, bạn có thể chạy lớp theo cùng một cách bằng cách khởi tạo và gọi phương thức được định nghĩa trong lớp CreateUsers.new.change.
VinnyQ77

13

Như rails 5bạn cũng có thể sử dụng railsthay vìrake

Đường ray 3 - 4

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

Đường ray 5

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

# or

rails db:migrate:up VERSION=20160920130051

1
nó cũng đoán những gì bạn cần vớirails db:migrate VERSION=20160920130051
frenesim

12

Nếu bạn gặp sự cố với đường dẫn, bạn có thể sử dụng

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

6

Cách 1:

rake db:migrate:up VERSION=20080906120000

Cách 2:

Trong Bảng điều khiển Rails 1. Sao chép dán lớp di chuyển trong bảng điều khiển (giả sử add_name_to_user.rb) 2. Sau đó, trong bảng điều khiển, nhập nội dung sau

Sharding.run_on_all_shards{AddNameToUser.up}

Xong rồi !!


5

Xin lưu ý rằng thay vì script/runner, bạn có thể phải sử dụng rails runnertrên các môi trường đường ray mới.


3

Nếu bạn muốn chạy nó từ bảng điều khiển, đây là những gì bạn đang tìm kiếm:

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

Tôi đã thử các câu trả lời khác, nhưng yêu cầu mà không Rails.rootlàm việc cho tôi.

Cũng thế, .migrate(:up) một phần buộc di chuyển để chạy lại bất kể nó đã chạy hay chưa. Điều này hữu ích khi bạn đã chạy di chuyển, loại bỏ nó bằng cách làm rối tung db và muốn một giải pháp nhanh chóng để thực hiện lại.


1

Có vẻ như ít nhất là trong bản phát hành Rails mới nhất (5.2 tại thời điểm viết bài), có một cách nữa để lọc các di chuyển đang được chạy. Người ta có thể vượt qua một bộ lọc trong mộtSCOPE biến môi trường mà sau đó sẽ được sử dụng để chọn các tệp di chuyển.

Giả sử bạn có hai tệp di chuyển 1_add_foos.rb2_add_foos.run_this_one.rbđang chạy

SCOPE=run_this_one rails db:migrate:up

sẽ chọn và chỉ chạy 2_add_foos.run_this_one.rb. Hãy nhớ rằng tất cả các tệp di chuyển phù hợp với phạm vi sẽ được chạy.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.