Есть ли какой-нибудь оптимизированный способ экспорта CSV из более чем одной записи lakh с использованием Rails? - PullRequest
0 голосов
/ 16 мая 2019

У меня есть 200 тыс. Мест в моей базе данных.Поэтому я хочу экспортировать все места в формат CSV.При этом загрузка занимает слишком много времени.Каков наилучший способ оптимизации кода в рельсах?

В контроллере:

 def index
    all_locations = Location.all
    respond_to do |format|
      format.csv { send_data all_locations.to_csv, filename: "locations-#{Date.today}.csv" }
    end
end

В модели

def self.to_csv
    attributes = %w{id city address}

    CSV.generate(headers: true) do |csv|
      csv << ['Id', 'City', 'Address']

      all.each do |location|
        csv << attributes.map{ |attr| location.send(attr) }
      end
    end
end

Ответы [ 2 ]

1 голос
/ 16 мая 2019

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

Ваша модель:

def self.to_csv
  attributes = %w{id city address}

  CSV.generate(headers: true) do |csv|
    csv << ['Id', 'City', 'Address']
    all.pluck(attributes).each { |data| csv << data }
  end
end

Используя pluck, вы получаете только те данные, которые вам нужны, а затем помещаете все эти данные в массив csv.

0 голосов
/ 16 мая 2019

если вы используете Postgresql , то вы можете использовать это в application_record.rb

def self.to_csv_copy(attrs="*", header=[])
  rc = connection.raw_connection
  rv = header.empty? ? [] : ["#{header.join(',')}\n"]
  sql = self.all.select(attrs).to_sql
  rc.copy_data("copy (#{sql}) to stdout with csv") do
    # rubocop:disable AssignmentInCondition
    while line = rc.get_copy_data
      rv << line
    end
  end
  rv.join
end

, а затем сделать

Location.to_csv_copy(%w{id city address}, ['Id', 'City', 'Address'])

Это даже быстрее, чемвышеуказанное решение.

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