2016-03-26 20 views
1

次のモデルがあります。以下のテーブルスキーマでRAKEタスクを使用してCSVをPOSTGRESリレーショナルDBに移動

class Lesson < ActiveRecord::Base 
    has_many :books 
    has_many :vocabularies 
    has_many :sentenses 
end 

class Book < ActiveRecord::Base 
    belongs_to :lesson 
end 

class Vocabulary < ActiveRecord::Base 
    belongs_to :lesson 
end 

class Sentense < ActiveRecord::Base 
    belongs_to :lesson 
end 

Table Lesson [lesson_number, lesson_name] 
Table Books [lesson_id, page_start, page_finish] 
Table Vocabulary [lesson_id, word, meaning] 
Table Sentences [lesson_id, sentence, sentence meaning] 

そして、私は15,000レッスンでCSVファイルを持っています。 CSVファイルは、2冊の同じ構造、10の語彙、すべてのレッスンプランで一貫して2つの文章を使用します。

私の考えは、このように始まります。

namespace :import_csv do 
    desc "IMPORT Lessons" 
    task :lessons => :environment do 
    CSV.foreach('CcyTbl.csv') do |row| 
     lesson_name_id = row[0] 
     lesson_name = row[1] 
     Lesson.create(lesson_name_id: lesson_name_id, lesson_name: lesson_name) 
    end 
    end 

    desc "IMPORT BOOKS" 
    task :books => :environment do 
    CSV.foreach('CcyTbl.csv') do |row| 
     lesson_name_id = row[0] 
     book_name = row[3] 
     book_start_pg = row[7] 
     book_end_pg = row[8] 
     Lesson.create(lesson_name_id: lesson_name_id, book_name: book_name, book_end_pg: book_end_pg) 
    end 
end 

それくらいまっすぐ進むようだが、私はに苦しんでいます:

NULL値を処理する方法
  1. いくつかの教訓が2冊 (列3は、BOOK1とBOOK2が列9で、時にはBOOK2がnullであると思います)
  2. 教訓5-10語彙 (カラム10語彙1、コラム11語彙1を持っているかもしれませんがあります意味、列12のボキャブラリーなど)

このCSVのデータをそれぞれのテーブルにインポートする最も良い方法は何ですか?各部分を行うために複数のレイクタスクを作成するのが理にかなっていますか、それとも一度に行うことができますか?ここ

UPDATE は、ヘッダ行のサンプルデータの最初の行にlinkです。 (画像を共有するには少し長すぎます)

+0

べきであるらしいです。ヌル値は物事をもっと複雑にしません。一部のCSVデータがモデルレベルの検証に失敗している場合は、検証を削除するか、デフォルト値を指定します。あなたが1つのレーキタスクを使うべきか、それとも多くを使うべきなのか、それは本当に重要なことではありません。あなたが1つのファイルで扱うのが大変だと思うときにあなたのコードを分岐してください。 –

+0

質問をヘッダとCSVファイルの最初のデータ行で更新できますか? – Dharam

+0

@DharamはGoogleドキュメントサンプルへのリンクを追加しました。そうでなければアップロードするには少し時間がかかりました。共有する方が良い場合は教えてください! – CheeseFry

答えて

1

CSVデータを扱いやすくするデータオブジェクトを作成したい場合があります。モデルの作成にCSV形式を切り離すこと、全体のプロセスを簡単にします:

csv = CSV.new(body, headers: true, header_converters: :symbol, converters: :all) 
data = csv.to_a.map {|row| row.to_hash } 

CSV referenceを参照してください。

各フィールドに簡単にアクセスできます。あなたは正しいアプローチを取っているよう

data.each do |d| 
    lesson = Lesson.create!(d[:join], ...) 
    book = Book.create!(lesson: lesson, page_start:..) 
end 

ところで& FWIW、

class Sentense < ActiveRecord::Base 

class Sentence < ActiveRecord::Base 
関連する問題