2016-03-26 1 views
1

У меня есть следующие модели.Использование RAKE Задача для перемещения CSV в реляционную базу данных POSTGRES

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] 

И у меня есть CSV-файл с 15000 уроков. 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 

Это очень похоже, прямо вперед, но я борюсь с:

  1. Как обработать нулевые значения.
  2. Некоторые уроки имеют две книги (Think колонка 3 имеет book1 и book2 является столбец 9, а иногда book2 равна нулю)
  3. Уроки могут иметь 5-10 слов словаря (колонка 10 лексикон 1, колонка 11 лексикон 1 значение, колонка 12 словаря и т. д.)

Каков наилучший способ импорта данных в этот CSV в их соответствующие таблицы? Имеет ли смысл создавать несколько рейк-задач для каждой части, или это можно сделать за один раз?

ОБНОВЛЕНИЕ Вот link к образцу строки заголовка и первой строки данных. (Слишком много времени, чтобы поделиться изображением.)

+0

кажется, что вы принимаете правильный подход. Нулевые значения не усложняют ситуацию. Если некоторые из ваших данных CSV терпят неудачу при проверке на уровне модели, либо удалите проверку, либо укажите значения по умолчанию. Что касается того, нужно ли использовать одну команду rake или много ... на самом деле это не важно, просто откройте свой код, если вы считаете, что его слишком много для обработки в одном файле. –

+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 

BTW & FWIW,

class Sentense < ActiveRecord::Base 

должен быть

class Sentence < ActiveRecord::Base 
Смежные вопросы