2013-09-02 46 views
18

Tôi đang làm việc trên một ứng dụng đã được triển khai cho một số hệ thống thử nghiệm và dàn dựng và các máy trạm phát triển khác nhau. Tôi cần phải thêm một số dữ liệu tham chiếu bổ sung nhưng tôi không chắc chắn cách thêm nó.Cách thêm dữ liệu hạt giống mới vào cơ sở dữ liệu đường ray hiện có

Hầu hết lời khuyên đều sử dụng seed.rb, tuy nhiên sự hiểu biết của tôi là điều này chỉ chạy một lần, khi ứng dụng được triển khai ban đầu. Vì chúng tôi không muốn xây dựng lại cơ sở dữ liệu thử nghiệm và dàn dựng để chúng tôi có thể thêm 1 hàng dữ liệu tham chiếu, có cách nào khác để thêm dữ liệu không?

Tôi đang nghĩ đến việc sử dụng di chuyển db, đây có phải là cách tiếp cận chính xác không?

Cảm ơn

+2

Bạn có thể chạy 'seed.rb' bao nhiêu lần tùy thích, nó chỉ là một tập lệnh ruby ​​bình thường ... Mặc dù bạn cần lưu ý rằng nếu bạn đã chạy nó trước và chạy lại, bạn sẽ nhận được các bản sao. Trong trường hợp của bạn nếu bạn muốn chỉ thêm một hàng dữ liệu, sau đó là một nhiệm vụ 'rake' hoặc sử dụng một tập lệnh runner http://guides.rubyonrails.org/command_line.html#rails-runner Tôi không nghĩ rằng di chuyển là thích hợp cho điều này mặc dù. – j03w

Trả lời

26

Cấu trúc tệp seed.rb của bạn để cho phép tạo và cập nhật dữ liệu liên tục. Bạn không bị giới hạn chỉ chạy một tệp hạt giống một lần và nếu bạn cho rằng nó chỉ được sử dụng cho triển khai ban đầu, bạn sẽ bỏ lỡ tính linh hoạt mà nó có thể cung cấp trong việc thiết lập dữ liệu tham chiếu.

Một tập tin hạt giống chỉ là ruby ​​để bạn có thể làm những việc như:

user = User.find_or_initialize_by(email: '[email protected]') 
user.name = 'Bob' 
user.password = 'secret' 
user.role = 'manager' 
user.save! 

này sẽ tạo dữ liệu mới nếu nó không tồn tại hoặc cập nhật dữ liệu nếu nó tìm thấy một số.

Nếu bạn cấu trúc tệp hạt giống của mình một cách chính xác, bạn cũng có thể tạo và cập nhật các đối tượng phụ thuộc.

Tôi khuyên bạn nên sử dụng lưu trữ bang để đảm bảo rằng các ngoại lệ được nêu ra trong trường hợp không thể lưu đối tượng. Đây là phương pháp dễ nhất để gỡ lỗi hạt giống.

Tôi sử dụng seedbank gem để cung cấp thêm cấu trúc cho dữ liệu hạt giống của mình, bao gồm thiết lập dữ liệu cho mỗi môi trường, hạt giống phụ thuộc và hơn thế nữa.

Tôi không khuyên bạn nên sử dụng di chuyển cho dữ liệu hạt giống. Có sự thiếu linh hoạt (làm thế nào để bạn nhắm mục tiêu dữ liệu hạt giống vào một môi trường chẳng hạn) và không có cách thực sự để xây dựng một tập hợp dữ liệu có thể sử dụng lại bất cứ lúc nào để làm mới một môi trường cụ thể. Bạn cũng sẽ có một tập hợp các di chuyển không có tham chiếu đến lược đồ của bạn và bạn sẽ phải tạo các lần di chuyển mới mỗi lần bạn muốn tạo dữ liệu mới hoặc thay đổi hiện tại.

+0

@ nmott- Sau khi thêm ở trên như nội dung tôi cần phải làm rake db: seed? Nếu tôi làm như vậy, những cái hiện có cũng được phổ biến một lần nữa ?? – Sam

+2

@Jsd Có, 'rake db: seed' sẽ tải tệp hạt giống và nếu một mô hình cụ thể đã tồn tại thì nó sẽ tìm thấy bản ghi và ghi đè lên nó bằng dữ liệu trong tệp hạt giống. Điều này có nghĩa là bạn có thể thay đổi dữ liệu trong ứng dụng của mình và sử dụng tệp hạt giống để làm mới dữ liệu đó trở lại bộ dữ liệu chuẩn một cách thường xuyên. – nmott

+0

Điều này có vẻ như nó cuối cùng sẽ nhận được khá cồng kềnh theo thời gian mặc dù. –

2

Bạn có thể sử dụng di chuyển, nhưng đó không phải là lựa chọn an toàn nhất mà bạn có. Ví dụ: bạn thêm bản ghi vào bảng thông qua di chuyển, sau đó trong tương lai bạn thay đổi lược đồ của bảng đó. Khi bạn cài đặt ứng dụng ở đâu đó, bạn sẽ không thể chạy rake db:migrate.

Hạt luôn được khuyến khích vì rake db:seed có thể chạy trên giản đồ được di chuyển hoàn toàn.

Nếu nó chỉ dành cho một bản ghi, hãy đi tới bảng điều khiển đường ray.

1

Tốt nhất là nên sử dụng một phương pháp idempotent như thế này trong seed.rb hoặc công việc khác được gọi bởi seed.rb:

Contact.find_by_email("[email protected]") || Contact.create(email: "[email protected]", phone: "202-291-1970", created_by: "System") 
# This saves you an update to the DB if the record already exists. 

Hoặc tương tự như @ nmott của:

Contact.find_or_initialize_by_email("[email protected]").update_attributes(phone: "202-291-1970", created_by: "System") 
# this performs an update regardless, but it may be useful if you want to reset your data. 

hoặc sử dụng assign_attributes thay của update_attributes nếu bạn muốn chỉ định nhiều thuộc tính trước khi lưu.

0

tôi đã làm một cái gì đó như thế này trong seed.rb

users_list = [ 
    {id: 1, name: "Diego", age: "25"}, 
    {id: 2, name: "Elano", age: "27"} 
] 

while !users_list.empty? do 
    begin 
    User.create(users_list) 
    rescue 
    users_list = users_list.drop(1) #removing the first if the id already exist. 
    end 
end 

Nếu một mục trong danh sách với id cho đã tồn tại nó sẽ trả về một ngoại lệ, sau đó chúng ta xóa mục đó và thử lại lần nữa, cho đến khi mảng users_list trống.

Bằng cách này bạn không cần phải tìm kiếm từng đối tượng trước khi bao gồm nó, nhưng bạn sẽ không thể cập nhật các giá trị đã chèn như trong mã @nmott.

0

Thay vì thay đổi seeds.db, mà bạn có thể muốn sử dụng để tạo cơ sở dữ liệu mới, bạn có thể tạo một nhiệm vụ Rake tùy chỉnh (RailsCast #66 Custom Rake Tasks).

Bạn có thể tạo bao nhiêu tác vụ Rake tùy thích. Ví dụ: giả sử bạn có hai máy chủ, một phiên bản đang chạy 1.0 của ứng dụng, một phiên bản đang chạy 1.1 và bạn muốn nâng cấp cả hai lên 1.2. Sau đó, bạn có thể tạo lib/tasks/1-0-to-1-2.rakelib/tasks`1-1-to-1-2.rake vì bạn có thể cần mã khác nhau tùy thuộc vào phiên bản ứng dụng của bạn.

1

Tôi sử dụng tệp hạt giống để thêm phiên bản vào bảng mới hoặc bảng hiện có mọi lúc. Giải pháp của tôi rất đơn giản. Tôi chỉ cần bình luận ra tất cả các dữ liệu hạt giống khác trong tệp db/seed.rb để chỉ có dữ liệu hạt giống mới là mã trực tiếp. Sau đó chạy bin/rake db:seed.

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