Ich versuche, eine tsv (Tab getrennt Datei) Datei in meine Datenbank zu importieren, nur ist es nicht richtig formatiert. Die Spalten price
und count
sind nur durch ein Leerzeichen getrennt (mit Ausnahme der Kopfzeile) und die Werte werden beide in den Schlüssel price
eingegeben, wobei alle Daten in falsche Schlüsselwertpaare verschoben werden.Schienen normalisieren csv-Dateidaten
tsv-Datei:
purchaser name item description price count merchant address merchant name
Alice Bob $10 off $20 of food 10.0 2 987 Fake St Bob's Pizza
Example Name $30 of awesome for $10 10.0 5 456 Unreal Rd Tom's Awesome Shop
Name Three $20 Sneakers for $5 5.0 1 123 Fake St Sneaker Store Emporium
John Williams $20 Sneakers for $5 5.0 4 123 Fake St Sneaker Store Emporium
in /models/purchase.rb
:
class Purchase < ActiveRecord::Base
# validates :item_price, :numericality => { :greater_than_or_equal_to => 0 }
def self.import(file)
CSV.foreach(file.path, :headers => true,
:header_converters => lambda { |h| h.downcase.gsub(' ', '_')},
:col_sep => "\t"
) do |row|
# debugger
purchase_hash = row.to_hash
Purchase.create!(purchase_hash)
end
end
end
Wenn ich die Datei und Kommentar im Debugger im Modell importieren und geben Sie dann row
es zurückgibt:
#<CSV::Row "purchaser_name":"Alice Bob" "item_description":"$10 off $20 of food" "price":"10.0 2" "count":" 987 Fake St" "merchant_address":" Bob's Pizza" "merchant_name":nil>
row.inspect
kehrt:
"#<CSV::Row \"purchaser_name\":\"Alice Bob\" \"item_description\":\"$10 off $20 of food\" \"price\":\"10.0 2\" \"count\":\" 987 Fake St\" \"merchant_address\":\" Bob's Pizza\" \"merchant_name\":nil>"
Wie Sie die price
(10.0) und count
(2) gestaucht wurden in den gleichen Wert sehen können, weil sie in der Datei nicht getrennt Tab waren.
db/schema.rb
:
ActiveRecord::Schema.define(version: 20160601205154) do
create_table "purchases", force: :cascade do |t|
t.string "purchaser_name"
t.string "item_description"
t.string "price"
t.string "count"
t.string "merchant_address"
t.string "merchant_name"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
Ich hatte ursprünglich price
als Dezimal-Datentyp und count
als Integer wechselte aber sie String zurück, um zu versuchen, eine Lösung zu finden. Ich kann sie zurück ändern, wenn es hilft (und würde es vorziehen, sie zurück zu ändern, wenn möglich)
Genau das, was ich brauchte, vielen Dank – alisontague