Tuesday 30 October 2007

FasterCSV problem - NoMethodError when trying to call join()

I've been getting this error message:

C:\work\reportscraper\db_uploader>ruby db_uploader.rb --file "Ethos Corporation.xls" > ethos.log

db_uploader.rb:147: undefined method `join' for #<FasterCSV::Row:0x2ea3ab0> (NoMethodError) from c:/ruby/lib/ruby/gems/1.8/gems/fastercsv-1.2.1/lib/faster_csv.rb:65

9:in `each' from c:/ruby/lib/ruby/gems/1.8/gems/fastercsv-1.2.1/lib/faster_csv.rb:65

9:in `each'

from db_uploader.rb:145

It's failing on this line:

data.each { |row|

>>> insert_sql = "INSERT INTO [DATA_UPLOADS] VALUES ( #{row.join(',')});"

puts insert_sql
#db.execute(insert_sql)
}


But I don't understand why this fails but the same method call in
another script is working:

def extract_data_from(filename)

data = FasterCSV.readlines(filename, {:col_sep=>"\t"})

end


cmdoptions = get_commandline_options

data = extract_data_from cmdoptions.single_file

puts
data.size


data.each { |row|
puts row.join(',')
}


==============

Just discovered why. Because in the code with the error, I was passing the :headers option.

data = FasterCSV.readlines(filename, {:col_sep=>"\t", :headers=> true})

In the code that was working, I was only specifying the column separator.

data = FasterCSV.readlines(filename, {:col_sep=>"\t"})

Adding this line

puts row.class

confirms this. The first loop was returning a Row while the second was returning an Array.

Just looked at the documentation and it's actually described in the RDoc:

http://fastercsv.rubyforge.org/fr_method_index.html

"This setting causes FasterCSV.shift() to return rows as FasterCSV::Row objects instead of Arrays and FasterCSV.read() to return FasterCSV::Table objects instead of an Array of Arrays."

No comments: