Cào chỉ một lần di chuyển


94

Tôi đang cố gắng chạy chỉ một lần di chuyển trong số toàn bộ ứng dụng rails của mình. Tôi có thể làm cái này như thế nào? Tôi không muốn thực hiện bất kỳ quá trình di chuyển nào trước hoặc sau nó. Cảm ơn.


1
Đây sẽ là một đường ray thuận tiện tính năng: thêm một STEP=ntham số để db:migrate(nơi nlà số di cư để chạy, giống như có cho db:rollback) - sau đó bạn có thể làm rake db:migrate STEP=1hoặc rake db:migrate STEP=2vv
user664833

Câu trả lời:


164

rake db:migrate:redo VERSION=xxxxxxx, nhưng điều đó sẽ chạy downvà sau đó là upbước. Bạn có thể làm điều này kết hợp với bình luận tạm thời ra bước xuống.


Rất tiếc, blog.stonean.com/2007/12/18/rake-dbmigrateredo , :: redo dường như không có đối số VERSION.
Terry G Lorber

3
@pedrorolo: Cái này không lỗi thời. Nhiệm vụ này không có mô tả và vì vậy nó sẽ không hiển thị trong rake -T.
Ryan Bigg

1
@pedrorolo: db:test:preparecũng không hiển thị trong danh sách đó. Chúa ơi, tôi đến trễ bữa tiệc.
mraaroncruz

9
Để mở rộng những gì Ryan nói, nếu bảng đã bị xóa khỏi cơ sở dữ liệu bên ngoài Rails, rake db:migrate:up VERSION=my_versioncó thể không làm gì cả , bởi vì bảng schema_migrations vẫn cho biết nó đã được chạy. Trong tình huống tương tự rake db:migrate:redo VERSION=my_versioncó thể thất bại vì nó không thể làm rơi bàn. Trong trường hợp này, hãy bình luận về downphương pháp trong quá trình di chuyển tạm thời và chạy lạirake db:migrate:redo...
Leo

3
Và để mở rộng những gì @Leo nói, nếu việc di chuyển được xác định với thay đổi def, thì hãy thay đổi nó thành def self.up ngoài những điều trên.
valk

70
rake db:migrate:up VERSION=1234567890

tương tự rake db:migrate:downđể giảm một quá trình di chuyển cụ thể. Bạn có thể nhận được danh sách các nhiệm vụ cào có sẵn với rake -T.


4
Giá trị VERSIONđược đề cập ở đây là giá trị số nguyên ở đầu mỗi tệp di chuyển của bạn (chỉ là dấu thời gian của thời điểm nó được tạo). Ví dụ VERSION=20150720023630,.
aaron mã hóa

3
Các phiên bản được hiển thị độc đáo với rake db: di chuyển: tình trạng
jpgeek

Đáng chú ý, VERSIONchỉ là một biến môi trường nên nó có thể xuất hiện đầu tiên trong lệnh hoặc thậm chí đặt trước lệnh:VERSION=1234567890 rake db:migrate:up
Joshua Pinter

25

Tôi đã phải chạy một lần di chuyển duy nhất đã thay đổi và cần được chạy lại một cách độc lập với tất cả các lần di chuyển khác. Khởi động bảng điều khiển và làm điều này:

>> require 'db/migrate/your_migrations.rb'
=> ["YourMigrations"]
>> YourMigrations.up
=> etc... as the migration runs
>> YourMigration.down

Hữu ích hơn, điều này có thể được đưa vào một nhiệm vụ cào, v.v.


6
Điều này hoạt động đáng kinh ngạc. Bạn cũng có thể chỉ cần sao chép và dán mã từ quá trình di chuyển vào bảng điều khiển để xác định lớp (và điều này cho phép thao tác thủ công nếu cần, ví dụ: nếu bạn vừa mắc lỗi trên Dev). Nếu bạn đã xác định một chuyển đổi có thể đảo ngược với change, hãy chạy YourMigrations.migrate(:up)thay thế (hoặc :downquá!)
trisweb

1
bạn có thể phảirequire "#{Rails.root}/db/migrate/your_migrations.rb"
s2t2

15

rake db:migrate:up VERSION=version_no

Sẽ di chuyển (thêm) tập lệnh di chuyển cụ thể

rake db:migrate:down VERSION=version_no

Sẽ xóa tập lệnh di chuyển cụ thể


10
rake db:migrate VERSION=20098252345

hãy thử xem.


7
Tôi nghĩ rằng điều này sẽ chạy bất kỳ quá trình di chuyển nào lên đến cái bạn đã chỉ định.
Ken Liu

1
đóng, nhưng điều đó cũng chạy bất kỳ quá trình di chuyển nào trước khi di chuyển cụ thể.
Anon

6
Tôi không nghĩ rằng bạn nên / muốn chỉ chạy một lần di chuyển mà không xem xét các lần di chuyển trước nó. Di chuyển là một đại diện của cấu trúc cơ sở dữ liệu vì nó liên quan đến mã tại một thời điểm nhất định, và do đó di chuyển trước khi cần thiết. Nếu bạn chỉ muốn chạy một lần di chuyển, có khả năng là bạn đã không viết các thao tác lên / xuống thích hợp để giữ cho quá trình di chuyển hoạt động ... đó là một thói quen xấu khi chỉ viết các di chuyển lên của bạn.
JP Silvashy

1
Đáng chú ý: VERSIONchỉ là một biến môi trường nên nó có thể xuất hiện đầu tiên trong lệnh hoặc thậm chí đặt trước lệnh:VERSION=20098252345 rake db:migrate
Joshua Pinter

4
rake db:migrate:redo version='xxxx'   

Hãy nhớ đặt dấu ngoặc kép xung quanh xxxx, xxxx là dấu thời gian (hoặc ID di chuyển) cho quá trình di chuyển của bạn.

Bạn có thể kiểm tra dấu thời gian (ID di chuyển) cho các lần di chuyển trước mà bạn đã thực hiện bằng cách sử dụng

rake db:migrate:status    

3

Mở rộng câu trả lời của korch ở trên, requirekhông hiệu quả với tôi, nhưng loadđã làm. Cụ thể, đối với tệp di chuyển:

    class ChangeMinQuantityToRaces < ActiveRecord::Migration
      def change
        change_column :races, :min_quantity, :integer, :default => 0
      end
    end

trong bảng điều khiển gõ

    > load 'db/migrate/30130925110821_change_min_quantity_to_races.rb'
    > ChangeMinQuantityToRaces.new.change

đã làm cho tôi.

    > Race.new.min_quantity # => 0 

Điều này dành cho ruby ​​1.9.3p484 (2013-11-22 sửa đổi 43786) [x86_64-linux] và Rails 3.2.13.


2

Thêm 2 ¢ của tôi vào điều này vì tôi đã gặp phải vấn đề tương tự:

Nếu bạn hoàn toàn muốn chạy lại quá trình di chuyển mà không cần tạo di chuyển mới, bạn có thể làm như sau:

rails dbconsole -p devdb=# delete from public.schema_migrations where version = '20150105181157';

Và rails sẽ "quên" rằng nó đã chạy quá trình di chuyển cho 20150105181157. Bây giờ khi bạn chạy db: migrate, nó sẽ chạy lại.

Mặc dù vậy, điều này hầu như luôn luôn là một ý tưởng tồi. Một ví dụ duy nhất mà nó có thể có ý nghĩa là nếu bạn có một nhánh phát triển và bạn vẫn chưa hoàn thiện quá trình di chuyển của mình và muốn thêm một số thứ vào nó trong quá trình phát triển. Nhưng ngay cả khi đó, tốt hơn là bạn nên thực hiện quá trình di chuyển của mình theo 2 chiều để bạn có thể khôi phục đúng cách và thử lại nhiều lần.


1

Phải có một cách để chạy lớp di chuyển thông qua bảng điều khiển. Tôi dường như không thể nhận ra mã di chuyển.

Tuy nhiên, như các nhận xét cho thấy, bạn nên chạy quá trình di chuyển theo thứ tự. Sử dụng:

rake db:migrate VERSION=##########

Sao chép và dán mã của bạn trong quá trình di chuyển sang tập lệnh / bảng điều khiển?



0

Tôi sử dụng kỹ thuật này trong quá trình phát triển khi tôi thay đổi một lượng lớn quá trình di chuyển và tôi không muốn di chuyển quá nhiều và mất bất kỳ dữ liệu nào trong quá trình đó (đặc biệt là khi tôi đang nhập dữ liệu kế thừa mất nhiều thời gian Tôi không muốn phải nhập lại lần nữa).

Đây là 100% hackish và tôi chắc chắn không khuyên bạn nên làm điều này trong sản xuất, nhưng nó sẽ thực hiện được mẹo:

  1. Di chuyển quá trình di chuyển mà bạn muốn chạy lại khỏi thư mục của nó đến một nơi tạm thời
  2. Tạo một di chuyển khác có cùng tên
  3. Sao chép / dán mã di chuyển ban đầu vào tệp di chuyển mới được tạo
  4. Chạy quá trình di chuyển mới
  5. Xóa tệp di chuyển mới được tạo
  6. Chỉnh sửa di chuyển giản đồ của bạn để xóa giá trị gần đây nhất
  7. Khôi phục tệp di chuyển cũ
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.