2014-09-05 14 views
13

Tôi có một bảng: db/di chuyển/20140731201801_create_voc_brands.rb:Rails 4. Di chuyển bảng id để UUID

class CreateVocBrands < ActiveRecord::Migration 
    def change 
    create_table :voc_brands do |t| 
     t.string :name 

     t.timestamps 
    end 
    end 
end 

Nhưng tôi cần phải thay đổi bảng này (nếu tôi sẽ tạo ra nó từ zero):

class CreateVocBrands < ActiveRecord::Migration 
    def change 
    create_table :voc_brands, :id => false do |t| 
     t.uuid :id, :primary_key => true 
     t.string :name 

     t.timestamps 
    end 
    add_index :voc_brands, :id 
    end 
end 

Làm cách nào để thay đổi điều này khi sử dụng di chuyển?

+0

Bạn có thể giải thích những gì bạn muốn làm không? Bạn đã di chuyển tệp này và muốn thực hiện thay đổi hay bạn muốn thực hiện thay đổi trong tệp di chuyển mới? – Mandeep

+0

Không, tôi không thực hiện bất kỳ thay đổi nào. Tôi có 1 lần di chuyển 'CreateVocBrands' (danh sách mã 1). Tôi cần phải chạy 'ChangeVocBrands'migration nhận được (câu hỏi là di chuyển) để thay đổi bảng thành danh sách 2d, nếu tôi tạo bảng VocBrand từ số – Derk153

+0

Tôi có thể hỏi tại sao bạn muốn' UUID' không? Chắc chắn bạn chỉ có thể áp dụng điều này như một cột riêng biệt, để lại khóa chính 'id'? Nếu bạn có lý do chính đáng, tôi sẽ giúp! –

Trả lời

23

Tôi gặp vấn đề tương tự như của bạn. Để di chuyển từ id mặc định để sử dụng uuid, tôi nghĩ bạn có thể một cái gì đó tương tự như những gì tôi đã có:

class ChangeVocBrandsPrimaryKey < ActiveRecord::Migration 
    def change 
    add_column :voc_brands, :uuid, :uuid, default: "uuid_generate_v4()", null: false 

    change_table :voc_brands do |t| 
     t.remove :id 
     t.rename :uuid, :id 
    end 
    execute "ALTER TABLE voc_brands ADD PRIMARY KEY (id);" 
    end 
end 
+5

Giải pháp hoạt động trong trường hợp này vì Voc_brands bảng không có dữ liệu, nếu không nó sẽ có khả năng làm hỏng dữ liệu, đặc biệt là nếu voc_brands có phụ thuộc. –

2

Tôi biết cuộc di cư này ưa thích cách để thực hiện bất kỳ thay đổi db nhưng dưới cách tiếp cận là tuyệt vời. Có thể sử dụng các truy vấn trực tiếp tới PostgreSQL để chuyển đổi bảng với dữ liệu hiện có.

Đối với khóa chính:

ALTER TABLE students 
     ALTER COLUMN id DROP DEFAULT, 
     ALTER COLUMN id SET DATA TYPE UUID USING (uuid(lpad(replace(text(id),'-',''), 32, '0'))), 
     ALTER COLUMN id SET DEFAULT uuid_generate_v4() 

Đối với tài liệu tham khảo khác:

ALTER TABLE students 
     ALTER COLUMN city_id SET DATA TYPE UUID USING (uuid(lpad(replace(text(city_id),'-',''), 32, '0'))) 

Các miếng đệm bên trái phía trên giá trị số nguyên với số không và chuyển đến một UUID. Cách tiếp cận này không yêu cầu ánh xạ id và nếu id cũ cần thiết có thể được lấy ra.

Vì không có sao chép dữ liệu, cách tiếp cận này hoạt động khá nhanh.

Để xử lý các trường hợp phức tạp và phức tạp hơn này của các hiệp hội đa hình, vui lòng sử dụng https://github.com/kreatio-sw/webdack-uuid_migration. Đá quý này bổ sung thêm những người trợ giúp cho ActiveRecord :: Migration để giảm bớt sự di trú này.

+1

Tôi biết đó là phần tốt hơn trong một năm nhưng tôi đã quay trở lại với mục đích duy nhất là upvoting bạn để tham khảo đá quý tại https://github.com/kreatio-sw/webdack-uuid_migration. Tôi tìm thấy một vấn đề với các tài liệu tham khảo chính nước ngoài và gửi một PR cho rằng ngày hôm nay, và có thể nói rằng ngay cả trên phiên bản 5.2.0.alpha của đường ray nó đã làm việc tuyệt vời! Chúng tôi đã cố gắng để làm điều tương tự này bằng tay vài tháng trước và nó đã vô cùng đau đớn. Cám ơn vì đã chia sẻ! +1 – Schwad

+0

Vâng ditto trên 'webdack-uuid_migration'! Trở lại để upvote này quá. Gói tuyệt vời đó là siêng năng hỗ trợ bởi người bảo trì của nó. Tôi nghĩ rằng nó sẽ có một cuộc sống lâu dài vì nó không đi điên rồ cố gắng để muck xung quanh với ActiveRecord internals. Chắc chắn đề nghị! – Kelseydh

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