Чтение и запись одного и того же CSV-файла в Ruby - PullRequest
0 голосов
/ 10 мая 2018

У меня есть некоторая обработка с использованием стороннего API, и я планировал использовать CSV-файл в качестве невыполненной работы.

Пример

Task to do   Resulting file
#1           data/1.json
#2           data/2.json
#3           

Итак, # 1 и # 2 уже сделаны. Я хочу работать над # 3 и сохранить файл CSV, как только data/3.json будет завершено.

Поскольку задача нестабильна и подвержена ошибкам, я хочу сохранить прогресс после каждой задачи в файле CSV.

Я написал этот сценарий на Ruby, он работает хорошо, но поскольку задач много (> 100 КБ), он записывает пару мегабайт на диск при каждой обработке задачи. Все это. Кажется, хороший способ убить мой HD:

class CSVResolver

  require 'csv'

  attr_accessor :csv_path

  def initialize csv_path:
    self.csv_path = csv_path
  end

  def resolve
    csv = CSV.read(csv_path)
    csv.each_with_index do |row, index|
      next if row[1] # Don't do anything if we've already processed this task, and got a JSON data
      json = very_expensive_task_and_error_prone
      row[1] = "/data/#{index}.json"
      File.write row[1], JSON.pretty_generate(json)
      csv[index] = row
      CSV.open(csv_path, "wb") do |old_csv|
        csv.each do |row|
          old_csv << row
        end
      end
      resolve
    end
  end

end

Есть ли способ улучшить это, например, сделать запись в CSV-файл атомарным?

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Для этой цели я бы использовал встроенную базу данных, такую ​​как SQLite или LevelDB.

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

0 голосов
/ 10 мая 2018

Для сохранения данных вам в большинстве случаев лучше всего выбрать инструмент, предназначенный для работы, базу данных. Вы уже назвали достаточно причин, чтобы не использовать конструкцию CSV с ручным вращением, поскольку она неэффективна с памятью и предлагает больше проблем, чем, вероятно, решает. Кроме того, в зависимости от объема данных, которые необходимо обработать с помощью API 3-ей части, вы можете обрабатывать многопоточные процессы, в которых чтение / запись в один файл не будет работать.

Возможно, вы захотите оформить заказ https://github.com/jeremyevans/sequel

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...