2013-09-02 5 views
18

Ich arbeite an einer Anwendung, die bereits für einige Test- und Staging-Systeme und verschiedene Entwickler-Workstations eingesetzt wird. Ich muss einige zusätzliche Referenzdaten hinzufügen, aber ich bin mir nicht sicher, wie ich es hinzufügen soll.So fügen Sie neue Seed-Daten zur vorhandenen Rails-Datenbank hinzu

Die meisten Ratschläge sagen seed.rb verwenden, aber mein Verständnis ist, dass dies nur einmal ausgeführt wird, wenn die Anwendung zunächst bereitgestellt wird. Da wir die Test- und Staging-Datenbanken nicht einfach so neu erstellen wollen, dass wir eine Zeile mit Referenzdaten hinzufügen können, gibt es eine andere Möglichkeit, die Daten hinzuzufügen?

Ich denke über die Verwendung einer DB-Migration, ist dies der richtige Ansatz?

Dank

+2

Sie können 'seed.rb' so oft wie Sie möchten ausführen, es ist nur eine normale Ruby-Skript-Datei ... Beachten Sie, dass Sie, wenn Sie es zuvor ausgeführt haben und es erneut ausführen, Duplikate erhalten. In Ihrem Fall, wenn Sie nur eine Reihe von Daten hinzufügen möchten, dann eine 'Rake-Task' oder verwenden Sie einen Skript-Runner http://guides.rubyonrails.org/command_line.html#rails-runner Ich denke nicht, dass Migration geeignet ist das obwohl. – j03w

Antwort

26

Strukturieren Sie Ihre Datei seed.rb, um die fortlaufende Erstellung und Aktualisierung von Daten zu ermöglichen. Sie sind nicht darauf beschränkt, eine Seed-Datei nur einmal auszuführen, und wenn Sie glauben, dass sie nur für die erste Bereitstellung verwendet wird, werden Sie die Flexibilität, die sie beim Einstellen von Referenzdaten bieten kann, übersehen.

Eine Seed-Datei Ruby nur so können Sie Dinge wie:

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

Diese neue Daten erstellen, wenn es nicht oder die Daten aktualisieren existiert, wenn es einige findet.

Wenn Sie Ihre Seed-Datei korrekt strukturieren, können Sie auch abhängige Objekte erstellen und aktualisieren.

Ich empfehle die Verwendung des Bang-Save, um sicherzustellen, dass Ausnahmen ausgelöst werden, falls ein Objekt nicht gespeichert werden kann. Dies ist die einfachste Methode, den Seed zu debuggen.

Ich verwende die seedbank gem, um mehr Struktur zu meinen Seed-Daten, einschließlich der Einstellung von Daten pro Umgebung, abhängige Samen und vieles mehr.

Ich empfehle nicht, Migrationen für Seed-Daten zu verwenden. Es gibt einen Mangel an Flexibilität (wie zielen Sie zum Beispiel auf Seed-Daten auf nur eine Umgebung ab) und keine echte Möglichkeit, einen wiederverwendbaren Satz von Daten aufzubauen, der jederzeit ausgeführt werden kann, um eine bestimmte Umgebung zu aktualisieren. Sie hätten auch eine Reihe von Migrationen, die keinen Bezug zu Ihrem Schema haben, und Sie müssten jedes Mal neue Migrationen erstellen, wenn Sie neue Daten generieren oder aktuelle Daten ändern möchten.

+0

@ nmott- Nach dem Hinzufügen von oben wie Inhalt sollte ich Rake db: samen tun müssen? Wenn es mir gefällt, sind die vorhandenen auch wieder bevölkert ?? – Sam

+2

@Jsd Ja, 'rake db: seed' lädt die Seed-Datei und wenn ein bestimmtes Modell bereits existiert, findet es den Datensatz und überschreibt ihn mit den Daten in der Seed-Datei. Dies bedeutet, dass Sie Daten in Ihrer App ändern und die Seed-Datei verwenden können, um sie regelmäßig auf einen Standarddatensatz zu aktualisieren. – nmott

+0

Dies scheint, als würde es mit der Zeit aber ziemlich aufgebläht werden. –

2

können Sie eine Migration verwenden, aber das ist nicht die sicherste Option, die Sie haben. Sagen Sie zum Beispiel, dass Sie einen Datensatz über eine Migration zu einer Tabelle hinzufügen, und später das Schema der Tabelle ändern. Wenn Sie die App irgendwo installieren, können Sie rake db:migrate nicht ausführen.

Seeds sind immer ratsam, da rake db:seed auf einem vollständig migrierten Schema ausgeführt werden kann.

Wenn es nur für eine Aufzeichnung ist, gehen Sie für die Schienenkonsole.

1

Am besten ist es eine idempotente Methode wie folgt in seed.rb oder einem anderen Aufgabe von seed.rb genannt zu verwenden:

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. 

Oder ähnlich wie @ nmott suchen:

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. 

oder verwenden assign_attributes statt von update_attributes, wenn Sie vor dem Speichern mehrere Attribute zuweisen möchten.

0

Ich habe so etwas wie dies in 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 

Wenn ein Element in der Liste mit der angegebenen ID existiert bereits eine Ausnahme zurück, wir dieses Element dann entfernen und es erneut versuchen, bis die Das Array users_list ist leer.

Auf diese Weise müssen Sie nicht jedes Objekt durchsuchen, bevor Sie es einschließen, aber Sie können nicht die Werte aktualisieren, die bereits wie in @nmott-Code eingefügt wurden.

0

Anstatt seeds.db zu ändern, die Sie wahrscheinlich für das Seeding neuer Datenbanken verwenden möchten, können Sie eine benutzerdefinierte Rake-Task erstellen (RailsCast #66 Custom Rake Tasks).

Sie können so viele Rake-Aufgaben erstellen, wie Sie möchten. Angenommen, Sie haben zwei Server, einen mit der Version 1.0 Ihrer App, den anderen mit 1.1, und Sie möchten beide auf 1.2 upgraden. Dann können Sie lib/tasks/1-0-to-1-2.rake und lib/tasks`1-1-to-1-2.rake erstellen, da Sie abhängig von der Version Ihrer App möglicherweise einen anderen Code benötigen.

1

Ich verwende die Seed-Datei, um Instanzen zu neuen oder vorhandenen Tabellen die ganze Zeit hinzuzufügen. Meine Lösung ist einfach. Ich gebe nur alle anderen Seed-Daten in der Datei db/seeds.rb aus, so dass nur die neuen Seed-Daten Live-Code sind. Führen Sie dann bin/rake db:seed.