Лучший способ читать CSV в Ruby. БыстрееCSV?

У меня есть файл CSV, который я хочу прочитать с помощью Ruby и создать объекты Ruby для вставки в базу данных MySQL с помощью Active Record. Как лучше всего это сделать? Я вижу два четких варианта: FasterCSV и Основной CSV-файл Ruby. Что лучше? Есть ли лучший вариант, который мне не хватает?

РЕДАКТИРОВАТЬ: Гарет говорит использовать FasterCSV, так как лучше всего читать файл CSV с помощью FasterCSV? Глядя на документацию, я вижу методы с именами parse, foreach, read, open... Там сказано, что foreach "предназначен в качестве основного интерфейса для чтения CSV-файлов". Так что, я думаю, я должен использовать это?


person ma11hew28    schedule 06.12.2010    source источник
comment
Я добавил тег MySQL, чтобы сделать его более заметным.   -  person the Tin Man    schedule 06.12.2010


Ответы (2)


Ruby 1.9 использует FasterCSV в качестве основного процессора CSV, поэтому я бы сказал, что определенно лучше использовать FasterCSV, даже если вы все еще используете Ruby 1.8.

person Gareth    schedule 06.12.2010
comment
Какая возможность для foreach пропустить первую строку (заголовок)? - person ma11hew28; 06.12.2010
comment
Документация (ruby-doc.org/ruby-1.9/classes/CSV .html#M001337) говорит, что параметры для foreach такие же, как параметры для CSV.new — ruby-doc.org/ruby-1.9/classes/CSV.html#M001346 - person Gareth; 06.12.2010
comment
Я понял это. Меня сбили с толку, потому что я пытался :headers => false. Думаю, теперь я понял. :headers => true это то, что я хотел. Он обрабатывает первую строку как строку заголовка и начинает со второй строки. Ха-ха. Я думал об этом с другой стороны. - person ma11hew28; 06.12.2010

Если вам нужно импортировать много записей, вы можете использовать файлы MySQL. загрузчик. Это будет очень быстро.

LOAD DATA INFILE может использоваться для чтения файлов, полученных из внешних источников. Например, многие программы могут экспортировать данные в формате значений, разделенных запятыми (CSV), так что строки имеют поля, разделенные запятыми и заключенные в двойные кавычки, с начальной строкой имен столбцов. Если строки в таком файле заканчиваются парами возврата каретки/новой строки, показанный здесь оператор иллюстрирует параметры обработки полей и строк, которые вы использовали бы для загрузки файла:

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
  FIELDS TERMINATED BY ',' ENCLOSED BY '"'
  LINES TERMINATED BY '\r\n'
  IGNORE 1 LINES;

Если входные значения не обязательно заключены в кавычки, используйте НЕОБЯЗАТЕЛЬНО перед ключевыми словами ENCLOSED BY.

Используйте это, чтобы вытащить все во временную таблицу, затем используйте ActiveRecord для выполнения запросов к ней, чтобы удалить записи, которые вам не нужны, затем скопируйте из временной таблицы в рабочую, затем удалите или усеките временную. Или используйте ActiveRecord для поиска во временной таблице и копирования записей в рабочую среду, а затем удалите или усеките временную таблицу. Возможно, вы даже сможете сделать копию таблицы в таблицу внутри MySQL или добавить одну таблицу к другой.

Будет сложно превзойти скорость выделенного загрузчика и использовать механизм запросов базы данных для массовой обработки записей. Шаг превращения записи в файле CSV в объект, а затем использование ORM для записи ее в базу данных добавляет много дополнительных накладных расходов, поэтому, если у вас нет сверхсложных проверок, требующих логики Ruby, вы будете быстрее идти прямо в базу данных.


РЕДАКТИРОВАТЬ: Вот простой пример отображения заголовка CSV в столбец БД:

require "csv"

data = <<EOT
header1, header2, header 3
1, 2, 3
2, 2, 3
3, 2, 3
EOT

header_to_table_columns = {
  'header1'  => 'col1',
  'header2'  => 'col2',
  'header 3' => 'col3'
}

arr_of_arrs = CSV.parse(data)
headers = arr_of_arrs.shift.map{ |i| i.strip }
db_cols = header_to_table_columns.values_at(*headers)
arr_of_arrs.each do |ary|
  # insert into the database using an ORM or by creating insert statements
end
person the Tin Man    schedule 06.12.2010