Импорт CSV в базу данных Rails

Ранее на этой неделе я задал этот вопрос, и он работал нормально. Я только что попробовал это с немного большей электронной таблицей, и по какой-то причине это не работает.

Мой код выглядит следующим образом:

require 'roo'

xlsx = Roo::Spreadsheet.open(File.expand_path('../Downloads/unistats/LOCATION.csv'))
xlsx.each_row_streaming(offset: 1) do |row|
    Location.find_or_create_by(ukprn: row[0].value, accomurl: row[1].value, instbeds: row[3].value, instlower: row[4].value, instupper: row[5].value, locid: row[6].value, locname: row[7].value, lat: row[9].value, long: row[10].value, locukprn: row[11].value, loccountry: row[12].value, privatelower: row[13].value, privateupper: row[14].value, suurl: row[15].value)
end

Но в отличие от прошлого раза, это происходит с этой ошибкой:

NoMethodError: undefined method `each_row_streaming' for #<Roo::CSV:0xb9e0b78>
Did you mean?  each_row_using_tempdir

Это файл CSV, а не .xlsx, но это не должно иметь значения.

Любые идеи, что я делаю неправильно?


person Dave C    schedule 25.01.2017    source источник
comment
Почему это не должно иметь значения?   -  person Mihai Dinculescu    schedule 25.01.2017
comment
Потому что в документации по гему Roo указано, что он работает с обоими типами файлов. Использование header = xlsx.row(1) показывает, что все столбцы находятся в ожидаемом месте.   -  person Dave C    schedule 25.01.2017
comment
Да, он может открыть его, но вы должны использовать другой метод для чтения значений.   -  person Mihai Dinculescu    schedule 25.01.2017


Ответы (1)


На самом деле имеет значение то, что вы пытаетесь прочитать CSV-файл, используя методы Excel.

Выдержки из документации Roo.

# Load a CSV file
s = Roo::CSV.new("mycsv.csv")

# Load a tab-delimited csv
s = Roo::CSV.new("mytsv.tsv", csv_options: {col_sep: "\t"})

# Load a csv with an explicit encoding
s = Roo::CSV.new("mycsv.csv", csv_options: {encoding: Encoding::ISO_8859_1})

Аккуратный способ чтения файлов Excel и CSV — сделать что-то вроде

if File.extname(filename).start_with?('xls')
  workbook = Roo::Excel.new(filename)  
else
  workbook = Roo::CSV.new(filename)
end

workbook.default_sheet = workbook.sheets[0]

(workbook.first_row..workbook.last_row).each do |line|
  ...
end
person Mihai Dinculescu    schedule 25.01.2017
comment
Тогда я попробую. - person Dave C; 25.01.2017
comment
Есть ли у вас какие-либо советы относительно того, как я могу поместить это в оператор each do? - person Dave C; 25.01.2017