Ich möchte Daten aus einer CSV-Datei in eine vorhandene Datenbanktabelle importieren. Ich möchte die CSV-Datei nicht speichern, sondern nur die Daten daraus entnehmen und in die vorhandene Tabelle einfügen. Ich benutze Ruby 1.9.2 und Rails 3.
Das ist mein Tisch:
create_table "mouldings", :force => true do |t|
t.string "suppliers_code"
t.datetime "created_at"
t.datetime "updated_at"
t.string "name"
t.integer "supplier_id"
t.decimal "length", :precision => 3, :scale => 2
t.decimal "cost", :precision => 4, :scale => 2
t.integer "width"
t.integer "depth"
end
Können Sie mir einen Code geben, der mir den besten Weg zeigt, danke?
ruby-on-rails
csv
import
am frischesten
quelle
quelle
Einfachere Version von yfeldblums Antwort, die einfacher ist und auch bei großen Dateien gut funktioniert:
Keine Notwendigkeit für with_indifferent_access oder symbolize_keys und keine Notwendigkeit, die Datei zuerst in eine Zeichenfolge einzulesen.
Es wird nicht die gesamte Datei auf einmal gespeichert, sondern zeilenweise eingelesen und ein Moulding pro Zeile erstellt.
quelle
Das
smarter_csv
Juwel wurde speziell für diesen Anwendungsfall erstellt: um Daten aus einer CSV-Datei zu lesen und schnell Datenbankeinträge zu erstellen.Sie können die Option verwenden
chunk_size
, um N CSV-Zeilen gleichzeitig zu lesen, und dann Resque in der inneren Schleife verwenden, um Jobs zu generieren, die die neuen Datensätze erstellen, anstatt sie sofort zu erstellen. Auf diese Weise können Sie die Last der Generierung von Einträgen verteilen an mehrere Arbeiter.Siehe auch: https://github.com/tilo/smarter_csv
quelle
Sie könnten versuchen
Upsert
:Wenn Sie dies wünschen, können Sie auch den Primärschlüssel mit automatischer Inkrementierung aus der Tabelle entfernen und den Primärschlüssel auf setzen
name
. Wenn es alternativ eine Kombination von Attributen gibt, die einen Primärschlüssel bilden, verwenden Sie diese als Selektor. Es ist kein Index erforderlich, es wird nur schneller.quelle
Das kann helfen. Es gibt auch Codebeispiele:
http://csv-mapper.rubyforge.org/
Oder für eine Rechenaufgabe, um dasselbe zu tun:
http://erikonrails.snowedin.net/?p=212
quelle
Es ist besser, den datenbankbezogenen Prozess in einen
transaction
Block zu packen . Code-Snippet-Blow ist ein vollständiger Prozess, bei dem eine Reihe von Sprachen in das Sprachmodell übernommen werden.Das folgende Snippet ist ein Teil der
languages.csv
Datei.quelle
Verwenden Sie dieses Juwel: https://rubygems.org/gems/active_record_importer
Dann können Sie jetzt verwenden:
Stellen Sie nur sicher, dass Ihre Überschriften mit den Spaltennamen Ihrer Tabelle übereinstimmen
quelle
Der bessere Weg ist, es in eine Rechenaufgabe aufzunehmen. Erstellen Sie die Datei import.rake in / lib / task / und fügen Sie diesen Code in diese Datei ein.
Führen Sie danach diesen Befehl in Ihrem Terminal aus
rake csv_model_import[file.csv,Name_of_the_Model]
quelle
Ich weiß, es ist eine alte Frage, aber es ist immer noch in den ersten 10 Links in Google.
Es ist nicht sehr effizient, Zeilen einzeln zu speichern, da dies zu Datenbankaufrufen in der Schleife führt und Sie dies besser vermeiden sollten, insbesondere wenn Sie große Datenmengen einfügen müssen.
Es ist besser (und wesentlich schneller), Batch-Insert zu verwenden.
Sie können eine solche Abfrage manuell erstellen und dann
Model.connection.execute(RAW SQL STRING)
(nicht empfohlen) oder gem verwendenactiverecord-import
(sie wurde erstmals am 11. August 2010 veröffentlicht). In diesem Fall legen Sie einfach Daten in ein Arrayrows
und rufen sie aufModel.import rows
Weitere Informationen finden Sie in den Gem-Dokumenten
quelle
Es ist besser, CSV :: Table zu verwenden und zu verwenden
String.encode(universal_newline: true)
. Es konvertiert CRLF und CR in LFquelle
Wenn Sie SmartCSV verwenden möchten
Dies stellt tabulatorgetrennte Daten in jeder Zeile dar,
"\t"
wobei die Zeilen durch neue Zeilen getrennt sind"\n"
quelle