81

Khi di chuyển đầu tiên, tôi khai báo trên cột content là chuỗi Activerecord biến chuỗi thành chuỗi (255) theo chú thích chú thích.Thay đổi loại cột thành chuỗi dài hơn trong đường ray

Sau khi tôi đẩy ứng dụng Heroku, trong đó sử dụng postgres, nếu tôi nhập theo hình thức trong nội dung một chuỗi dài hơn 255 Tôi nhận được lỗi

PGError: ERROR: value too long for type character varying(255) 

Vấn đề là tôi cần phải có nội dung chứa một chuỗi điều đó cực kỳ dài (văn bản tự do, có thể là hàng nghìn ký tự)

  1. Biến nào (chuỗi này không thích hợp cho điều này) sẽ chấp nhận?
  2. Làm thế nào để tạo ra một sự chuyển đổi để thay thế các loại cột đó

nhờ

Trả lời

193

Bạn nên sử dụng text với Rails nếu bạn muốn có một chuỗi không có giới hạn độ dài. Di chuyển như sau:

def up 
    change_column :your_table, :your_column, :text 
end 
def down 
    # This might cause trouble if you have strings longer 
    # than 255 characters. 
    change_column :your_table, :your_column, :string 
end 

nên sắp xếp mọi thứ. Bạn có thể muốn :null => false hoặc một số tùy chọn khác vào cuối quá.

Khi bạn sử dụng cột string không có giới hạn rõ ràng, Rails sẽ thêm một ẩn ngụ :limit => 255. Nhưng nếu bạn sử dụng text, bạn sẽ nhận được bất kỳ loại chuỗi dài tùy ý nào mà cơ sở dữ liệu hỗ trợ. PostgreSQL cho phép bạn sử dụng một cột varchar mà không có chiều dài nhưng hầu hết các cơ sở dữ liệu sử dụng một loại riêng biệt cho điều đó và Rails không biết về varchar mà không có chiều dài. Bạn phải sử dụng text trong Rails để nhận số text column trong PostgreSQL. Không có sự khác biệt trong PostgreSQL giữa một cột thuộc loại text và một loại varchar (nhưng varchar(n) khác nhau). Hơn nữa, nếu bạn đang triển khai trên đầu trang của PostgreSQL, không có lý do gì để sử dụng :string (AKA varchar), cơ sở dữ liệu xử lý textvarchar(n) nội bộ ngoại trừ các giới hạn chiều dài thêm cho varchar(n); bạn chỉ nên sử dụng varchar(n) (AKA :string) nếu bạn có ràng buộc bên ngoài (chẳng hạn như biểu mẫu của chính phủ cho biết trường 432 trên biểu mẫu 897/B sẽ dài 23 ký tự) trên kích thước cột. Ngoài ra, nếu bạn đang sử dụng cột string ở bất cứ nơi nào, bạn nên luôn luôn chỉ định :limit như một lời nhắc nhở cho chính mình rằng có giới hạn và bạn phải có xác thực trong mô hình để đảm bảo rằng giới hạn không được vượt quá . Nếu bạn vượt quá giới hạn, PostgreSQL sẽ khiếu nại và đưa ra một ngoại lệ, MySQL sẽ lặng lẽ cắt bớt chuỗi hoặc phàn nàn (tùy thuộc vào cấu hình máy chủ), SQLite sẽ cho phép nó vượt qua, và các cơ sở dữ liệu khác sẽ làm điều gì đó khác (có thể là phàn nàn) .

Ngoài ra, bạn cũng nên phát triển, thử nghiệm và triển khai trên cùng cơ sở dữ liệu (thường sẽ là PostgreSQL tại Heroku), thậm chí bạn nên sử dụng cùng một phiên bản của máy chủ cơ sở dữ liệu. Có những khác biệt khác giữa các cơ sở dữ liệu (chẳng hạn như hành vi của GROUP BY) mà ActiveRecord sẽ không cách ly bạn. Bạn có thể đã làm điều này nhưng tôi nghĩ tôi sẽ đề cập đến nó.

+13

Great câu trả lời. Một lưu ý: Rails hiện không hỗ trợ change_column với phương thức thay đổi (http://guides.rubyonrails.org/migrations.html#using-the-change-method); nếu bộ nhớ phục vụ, bạn sẽ tạo ra một di chuyển không thể đảo ngược nếu bạn làm điều đó. Tốt hơn là nên làm theo cách cũ của trường với các phương pháp lên/xuống. – poetmountain

+0

@BourbonJockey: Có nghĩa là 'thay đổi' sẽ không thể tự động đảo ngược thay đổi loại và [Hướng dẫn di chuyển] (http://guides.rubyonrails.org/migrations.html#anatomy-of-a- di chuyển) nói rằng "[phương pháp thay đổi] Phương pháp này được ưu tiên để viết di chuyển xây dựng (thêm cột hoặc bảng)" và 'change_column' không có trong danh sách bạn trỏ vào để tôi nghĩ bạn đúng. Tôi cố định nó để sử dụng 'up' /' down' (với lời cảnh báo về 'down'), cảm ơn những người đứng đầu. –

+4

Để tham khảo trong tương lai của người đọc khác, chuyển đổi từ chuỗi thành văn bản trong Postgres trên Heroku theo cách này sẽ KHÔNG mất dữ liệu. –

0

Trong khi câu trả lời được chấp nhận là tuyệt vời, tôi muốn thêm câu trả lời ở đây hy vọng thỏa thuận tốt hơn với câu hỏi áp phích gốc phần 2, cho các chuyên gia không thích bản thân tôi.

  1. How do I create a migration to replace the type of that column

tạo giàn giáo di cư

Bạn có thể tạo ra một sự chuyển đổi để giữ sự thay đổi của bạn bằng cách gõ vào giao diện điều khiển của bạn (chỉ cần thay thế các table cho tên bảng của bạn, và column cho bạn tên cột)

rails generate migrate change_table_column 

Điều này sẽ tạo ra sự di chuyển bộ xương bên trong ứng dụng Rails/db/migrate/folder. Di chuyển này là trình giữ chỗ cho mã di chuyển của bạn.

Ví dụ tôi muốn tạo một sự chuyển đổi để thay đổi kiểu của một cột string-text, trong một bảng gọi là TodoItems:

class ChangeTodoItemsDescription < ActiveRecord::Migration 
    def change 
    # enter code here 
    change_column :todo_items, :description, :text 
    end 
end 

Chạy chuyển đổi của bạn

Một khi bạn đã đã nhập mã để thay đổi cột vừa chạy:

rake db:migrate 

Để áp dụng di chuyển của bạn trên. Nếu bạn thực hiện một lỗi mà bạn luôn có thể phục hồi các thay đổi với:

rake db:rollack 

Up and Down phương pháp

Các tài liệu tham khảo câu trả lời chấp nhận UpDown phương pháp, thay vì phương pháp mới hơn Change. Vì đường ray 3.2kiểu cũ Phương thức lên và xuống đã trình bày một số lợi thế so với phương pháp Thay đổi mới hơn. 'Lên và xuống' tránh ActiveRecord::IrreversibleMigration exception. Kể từ khi phát hành Rails 4 bạn có thể sử dụng reversible để tránh lỗi này:

class ChangeProductsPrice < ActiveRecord::Migration 
    def change 
    reversible do |dir| 
     change_table :products do |t| 
     dir.up { t.change :price, :string } 
     dir.down { t.change :price, :integer } 
     end 
    end 
    end 
end 

Thưởng thức Rails :)

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