Импортировать 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