2012-01-10 43 views
31

Tôi dường như không thể tìm thấy một tùy chọn hoặc bất cứ điều gì cho phép tôi bỏ qua di chuyển.Làm cách nào để bỏ qua di chuyển không thành công? (rake db: migrate)

Tôi biết những gì bạn đang nghĩ: "Bạn không bao giờ phải làm điều đó ..."

tôi cần phải bỏ qua một sự chuyển đổi mà làm thay đổi hồ sơ người dùng cụ thể không tồn tại trong cơ sở dữ liệu phát triển của tôi . Tôi không muốn thay đổi di chuyển vì nó không phải là một phần của nguồn mà tôi phải làm việc cùng. Có cách nào để bỏ qua di chuyển hoặc bỏ qua di chuyển không thành công không?

Cảm ơn trước!

Trả lời

53

Tôi nghĩ bạn nên khắc phục sự di chuyển vi phạm ít mong manh hơn, tôi đoán rằng một vài câu hỏi if và có lẽ là rescue là đủ.

Nhưng, nếu sửa chữa di chuyển thực sự không phải là một tùy chọn, bạn có thể giả mạo nó theo nhiều cách khác nhau. Trước hết, bạn chỉ có thể bình luận ra các phương pháp di chuyển, chạy rake db:migrate, và sau đó bỏ ghi chú (hoặc hoàn nguyên) việc di chuyển vi phạm.

Bạn cũng có thể giả mạo nó bên trong cơ sở dữ liệu nhưng loại này không được khuyến khích trừ khi bạn biết bạn đang làm gì và bạn không ngại vá những thứ khi bạn (chắc chắn) mắc lỗi. Có một bảng trong cơ sở dữ liệu của bạn có tên là schema_migrations có một cột varchar(255) duy nhất được gọi là version; bảng này được sử dụng bởi db:migrate để theo dõi việc di chuyển nào đã được áp dụng. Tất cả những gì bạn cần làm là INSERT giá trị version thích hợp và rake db:migrate sẽ nghĩ rằng quá trình di chuyển đã được thực hiện. Tìm file vi phạm di cư:

db/migrate/99999999999999_XXXX.rb 

sau đó đi vào cơ sở dữ liệu của bạn và nói:

insert into schema_migrations (version) values ('99999999999999'); 

nơi 99999999999999 là, tất nhiên, số lượng từ tên tập tin của di cư. Sau đó, chạy rake db:migrate nên bỏ qua việc di chuyển đó.

Tôi muốn sử dụng tùy chọn thứ hai trước thứ ba, tôi chỉ bao gồm tùy chọn "hack schema_versions" để hoàn tất.

+0

Ya, tôi chỉ cần đi trước và cắt ra những cuộc di cư vi phạm tạm thời. Cá nhân tôi đã tạo ra các câu lệnh If đúng hoặc chỉ kiểm tra môi trường sản xuất, nhưng rõ ràng là người xử lý việc di chuyển không tin vào việc sử dụng db: di chuyển trong khi phát triển = P Thanks – hmind

+0

@hmind: "người xử lý di chuyển không tin vào việc sử dụng db: di chuyển trong khi phát triển ". Ôi trơi. Xuất bản cho hệ thống sản xuất của bạn phải là một thời gian vui vẻ siêu hạnh phúc! –

+2

may mắn thay, tôi không xử lý hoặc haha ​​ – hmind

1

Thay vì bỏ qua sự di cư bạn có thể làm chuyển đổi của bạn thông minh, thêm một số IF để nó, vì vậy bạn có thể kiểm tra "người dùng cụ thể"

+0

Phải, đó là những gì tôi đã làm nếu tôi đã viết di chuyển. Nhưng tôi đã không và tôi không thực sự muốn xung quanh với một phần của nguồn mà tôi không phải thực sự liên lạc vì vậy tôi chỉ kết thúc cắt chúng ra tạm thời. – hmind

14

Đây là một cách tốt để làm điều đó cho lỗi một lần.

db:migrate:up VERSION=my_version

Điều này sẽ chạy một hành động "lên" di chuyển cụ thể. (Ngoài ra, ngược lại nếu bạn cần nó, chỉ cần thay thế "up" bằng "down".) Vì vậy, theo cách này bạn có thể chạy di chuyển trong tương lai mà làm cho cái cũ hơn (mà bạn cần bỏ qua) làm việc, hoặc chỉ chạy mỗi di chuyển trước nó một cách có chọn lọc.

Tôi cũng tin rằng bạn có thể làm lại cuộc di cư theo cách này:

rake db:migrate:redo VERSION=my_version

tôi đã không thử phương pháp mà cá nhân, do đó, YMMV.

1

đôi khi, nó là cần thiết để tái điền schema_migrations bảng với di cư chắc chắn đúng ... CHỈ cho mục đích này tôi đã tạo ra phương pháp này

def self.insert_missing_migrations(stop_migration=nil) 
    files = Dir.glob("db/migrate/*") 
    timestamps = files.collect{|f| f.split("/").last.split("_").first} 
    only_n_first_migrations = timestamps.split(stop_migration).first 

    only_n_first_migrations.each do |version| 
    sql = "insert into `schema_migrations` (`version`) values (#{version})" 
    ActiveRecord::Base.connection.execute(sql) rescue nil 
    end 
end 

bạn có thể sao chép-dán nó vào bất kỳ mô hình bạn muốn và sử dụng nó từ giao diện điều khiển

YourModel.insert_missing_migrations("xxxxxxxxxxxxxx") 

(hoặc bằng cách nào đó khác)

nơi "xxxxxxxxxxxxxx" - là dấu thời gian của di cư trước khi mà bạn muốn dừng chèn (bạn có thể để nó trống)

!!! sử dụng nó chỉ khi bạn hoàn toàn hiểu được kết quả bạn sẽ nhận được !!!

10

Tôi đã có một vấn đề mà tôi đã có một chuyển đổi để thêm một bảng đã tồn tại, vì vậy trong trường hợp của tôi, tôi đã phải bỏ qua sự chuyển đổi này là tốt, bởi vì tôi đã nhận được báo lỗi

SQLite3::SQLException: table "posts" already exists: CREATE TABLE "posts" 

tôi chỉ đơn giản đã nhận xét nội dung của phương thức tạo bảng, chạy di chuyển và sau đó bỏ ghi chú đó ra. Đó là một cách thủ công để vượt qua nó, nhưng nó hoạt động. Xem bên dưới:

class CreatePosts < ActiveRecord::Migration 
    def change 
    # create_table :posts do |t| 
    # t.string :title 
    # t.text :message 
    # t.string :attachment 
    # t.integer :user_id 
    # t.boolean :comment 
    # t.integer :phase_id 

    # t.timestamps 
    # end 
    end 
end 
+0

Đây chỉ là tuyệt vời !!! Không thể tin rằng tôi không nghĩ về điều này. Hoàn toàn làm việc. – helpse

7

Nếu bạn phải làm điều đó, việc di chuyển ứng dụng của bạn bị rối tung!

Chèn tất cả di cư mất tích:

def insert(xxx) 
    ActiveRecord::Base.connection.execute("insert into schema_migrations (version) values (#{xxx})") rescue nil 
end 

files = Dir.glob("db/migrate/*") 
files.collect { |f| f.split("/").last.split("_").first }.map { |n| insert(n) } 
+1

Không nhất thiết. Ví dụ, nếu bạn pg_restore cơ sở dữ liệu sản xuất của bạn để máy phát triển của bạn để khắc phục sự cố với dữ liệu sản xuất. Đừng nhanh chóng nói với ai đó rằng họ đang làm sai khi bạn không có đủ thông tin. –

+0

@MikeBethany: Trong trường hợp của tôi đó là khi tôi phải sử dụng nó, mọi thứ đều là một mớ hỗn độn lớn và tôi không có thời gian để hiểu tại sao nó lại như thế. Về pg_restore, nó cũng nên khôi phục bảng 'schema_migrations' mà tôi đoán đúng không? – Dorian

+0

Vâng, tất nhiên, bảng 'schema_migrations' chỉ là một bảng trong cơ sở dữ liệu. Đọc lại tên sách của bạn tôi có thể thấy một cách giải thích khác. Ban đầu tôi đọc nó là, "Bạn đã không viết di chuyển của bạn đúng cách." Những gì tôi nghĩ rằng bạn thực sự có nghĩa là, "Có một vấn đề với di chuyển." Nhưng đó là hiển nhiên, do đó, câu hỏi, vì vậy tôi giả định "bạn hơi say lên" ý nghĩa. Lỗi của tôi. –

Các vấn đề liên quan