使用 RAKE 任务将 CSV 移动到 POSTGRES 关系数据库
Use RAKE Task to move CSV to POSTGRES relational 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 架构:
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
这似乎很简单,但我正在努力:
- 如何处理空值。
- 有些课有两本书
(认为第 3 列有 book1,book2 是第 9 列,有时 book2 为空)
- 课程可能包含 5-10 个词汇
(第10栏词汇1,第11栏词汇1含义,第12栏词汇等)
将此 CSV 中的数据导入各自的 table 的最佳方法是什么?创建多个 rake 任务来完成每个部分是否更有意义,还是可以一次性完成?
更新
这是 link 到 header 行和第一行数据的示例。
(分享图片有点长。)
您可能想要创建一个数据对象,以便更轻松地处理 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
我有以下型号。
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 架构:
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
这似乎很简单,但我正在努力:
- 如何处理空值。
- 有些课有两本书 (认为第 3 列有 book1,book2 是第 9 列,有时 book2 为空)
- 课程可能包含 5-10 个词汇 (第10栏词汇1,第11栏词汇1含义,第12栏词汇等)
将此 CSV 中的数据导入各自的 table 的最佳方法是什么?创建多个 rake 任务来完成每个部分是否更有意义,还是可以一次性完成?
更新 这是 link 到 header 行和第一行数据的示例。 (分享图片有点长。)
您可能想要创建一个数据对象,以便更轻松地处理 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