CSV-импорт в Rails - неверная последовательность байтов в UTF-8 с неанглийскими символами - PullRequest
3 голосов
/ 09 сентября 2011

Я использую CSVMapper Gem для импорта некоторых записей в CSV-файле в модель Rails 3. (Я использовал этот драгоценный камень, потому что это то, что я нашел самый простой способ сделать это)

В любом случае, код, который я использую для импорта записей, следующий:

r = import('doc/socios_full.csv') do
    map_to Associate
    after_row lambda{|row, associate| associate.save }
    start_at_row 1
    [group,member,family_relationship_code,family_relationship_description,last_name,names,...]
#The previous line is actually longer, with more atts, but it's been cut to explain the example
end

И это работает очень хорошо, кроме случаев, когда парсер встречает некоторые неанглийские символы, такие как ó, é, ñ, í, °.... Вот тогда я получаю следующую ошибку:

ArgumentError: invalid byte sequence in UTF-8
    from /home/bcb/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1831:in `sub!'
    from /home/bcb/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1831:in `block in shift'
    from /home/bcb/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1825:in `loop'
    from /home/bcb/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1825:in `shift'
    from /home/bcb/.rvm/rubies/ruby-1.9.2-p136/lib/ruby/1.9.1/csv.rb:1767:in `each'
    from /home/bcb/.rvm/gems/ruby-1.9.2-p136/gems/csv-mapper-0.5.1/lib/csv-mapper.rb:106:in `each_with_index'
    from /home/bcb/.rvm/gems/ruby-1.9.2-p136/gems/csv-mapper-0.5.1/lib/csv-mapper.rb:106:in `import'
    from (irb):63
    from /home/bcb/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in `start'
    from /home/bcb/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.9/lib/rails/commands/console.rb:8:in `start'
    from /home/bcb/.rvm/gems/ruby-1.9.2-p136/gems/railties-3.0.9/lib/rails/commands.rb:23:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

Я действительно уверен в этом, потому что, если я заменю все эти символы, проблема исчезнет, ​​пока парсер не найдет другой неанглоязычный символ. Дело в том, что у меня есть файл с записями по 50 тыс., Поэтому поиск каждого символа, который я могу придумать, и попытка импортировать все эти записи каждый раз очень трудоемки.

Есть ли способ игнорировать эти ошибки и позволить анализатору продолжить работу? Или есть более простой способ импортировать этот файл CSV?

Ответы [ 4 ]

14 голосов
/ 30 августа 2013

Сделайте так:

CSV.foreach(filename, :headers => true , :encoding => 'ISO-8859-1') do |row|

У меня возникла та же проблема при попытке прочитать файл CSV, сохраненный в MS Excel.Вы можете указать кодировку в качестве опции.Я предполагаю, что по умолчанию предполагается UTF-8.

3 голосов
/ 10 сентября 2011

Решено с помощью другого подхода, это гораздо более простое решение для импорта файлов CSV в модель Rails 3, чем с использованием внешнего гема:

    require 'csv'
    CSV.foreach('doc/socios_full.csv') do |row|
        record = Associate.new(
            :media_format   => row[0], 
            :group => row[0],
            :member => row[1],
            :family_relationship_code => row[2],
            :family_relationship_description => row[3],
            :last_name => row[4],
            :names => row[5],
            ...
        )
        record.save!
    end

Это работает безупречно, даже с неанглийскими символами (только что попробовал файл импорта 75k!). Надеюсь, это кому-нибудь пригодится.

1 голос
/ 09 сентября 2011

Может быть, вы можете попробовать что-то вроде этого:

csv_string.force_encoding('ISO-8859-1')
0 голосов
/ 22 января 2014

Следующий подход должен работать в любой модели, если вы уверены, что CSV будет содержать правильные имена заголовков:

  def self.import(file)
    CSV.foreach(file.path, headers: true) do |row|
      obj = self.new
      obj.attributes.each_key do |attribute|
        index = row.headers.index(attribute)
        obj.send("#{attribute}=",row[index]) if index
      end
      obj.save
    end
  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...