Импортировать CSV партиями в Rails?

Я использую FasterCSV для импорта загруженного файла в модель, и он отлично работает для небольших файлов. Однако, когда я пытаюсь импортировать большой набор данных (21 000 строк), это занимает много времени, и я получаю тайм-ауты браузера на живом сервере.

Это мой текущий рабочий код:

  logcount=0
  Attendee.transaction do
    FCSV.new(file, :headers => true).each do |row|
      row[1] = Date.strptime(row[1], '%m/%d/%Y')
      record = @event.attendees.new(:union_id => row[0], :dob => row[1], :gender => row[2])
      if record.save
        logcount += 1
      end
    end
  end

Я бы хотел использовать фоновый процесс, но пользователь должен увидеть, сколько строк было импортировано, прежде чем они смогут перейти к следующему шагу системы.

Итак, я подумал, что мне следует использовать чанки действий и читать только меньшее количество строк, установить счетчик, затем обновить представление с некоторым прогрессом, а затем снова запустить метод, используя предыдущий счетчик в качестве начальной точки.

Кажется, я не вижу, как заставить FasterCSV читать только определенное количество строк, а также установить смещение для начальной точки.

Кто-нибудь знает как это сделать? Или есть лучший способ справиться с этим?

3 ответа

Решение

Попробуйте AR Import

Старый ответ

Вы пытались использовать AR-расширения для массового импорта? Вы получаете впечатляющие улучшения производительности, когда вы вставляете тысячи строк в БД. Посетите их сайт для более подробной информации.

Я предпочел бы создать подготовленный запрос, загрузить строку из файла и выполнить подготовленный запрос. Без какого-либо использования модели, должно быть быстрее.

Если у вас есть база данных, почему бы не импортировать ее через Rake Task? Собираются ли ваши пользователи импортировать такие большие базы данных?

Если ваши пользователи будут импортировать такую ​​большую базу данных, задача не будет выполнена.

FCSV.new может принять любые варианты IO.open может. Вы можете использовать это для поиска определенного байта. К сожалению, FCSV не позволяет легко остановить или получить доступ к базовому объекту ввода-вывода, чтобы узнать, где вы остановились. Возобновление в середине файла также усложняет использование строки заголовка.

На самом деле, я думаю, что оптимальным решением является аутсорсинг импорта CSV-файла в drb, который периодически сообщает о своем прогрессе таким образом, чтобы можно было выполнить действие контроллера. Затем вызывайте это действие контроллера каждый раз, когда какой-нибудь AJAX работает на клиенте.

Я имел успех с BackgroundDRb в прошлом. Его установка и использование слишком подробны для меня, чтобы воспроизвести здесь. Есть другие плагины и гемы, доступные с небольшим количеством прибегая к помощи.

Предупреждение о DRb Для большинства решений DRb требуется дополнительный демон-процесс, работающий на вашем сервере. некоторые веб-хостинги запрещают это в более простых планах. Проверьте свои TOS

Другие вопросы по тегам