ruby-on-rails - 高效的批量更新 rails 数据库

标签 ruby-on-rails activerecord bulkinsert

我正在尝试构建一个 rake 实用程序,它会经常更新我的数据库。

这是我到目前为止的代码:

namespace :utils do

  # utils:update_ip
  # Downloads the file frim <url> to the temp folder then unzips it in <file_path>
  # Then updates the database.

  desc "Update ip-to-country database"
  task :update_ip => :environment do

    require 'open-uri'
    require 'zip/zipfilesystem'
    require 'csv'

    file_name = "ip-to-country.csv"
    file_path = "#{RAILS_ROOT}/db/" + file_name
    url = 'http://ip-to-country.webhosting.info/downloads/ip-to-country.csv.zip'


    #check last time we updated the database.
    mod_time = ''
    mod_time = File.new(file_path).mtime.httpdate    if File.exists? file_path

    begin
      puts 'Downloading update...'
      #send conditional GET to server
      zipped_file = open(url, {'If-Modified-Since' => mod_time})
    rescue OpenURI::HTTPError => the_error
      if the_error.io.status[0] == '304'
        puts 'Nothing to update.'
      else
        puts 'HTTPError: ' + the_error.message
      end
    else # file was downloaded without error.

      Rails.logger.info 'ip-to-coutry: Remote database was last updated: ' + zipped_file.meta['last-modified']
      delay = Time.now - zipped_file.last_modified
      Rails.logger.info "ip-to-country: Database was outdated for: #{delay} seconds (#{delay / 60 / 60 / 24 } days)"

      puts 'Unzipping...'
      File.delete(file_path) if File.exists? file_path
      Zip::ZipFile.open(zipped_file.path) do |zipfile|
        zipfile.extract(file_name, file_path)
      end

      Iptocs.delete_all

      puts "Importing new database..."


      # TODO: way, way too heavy find a better solution.


      CSV.open(file_path, 'r') do |row|
        ip = Iptocs.new(  :ip_from        => row.shift,
                        :ip_to          => row.shift,
                        :country_code2  => row.shift,
                        :country_code3  => row.shift,
                        :country_name   => row.shift)
        ip.save
      end #CSV
      puts "Complete."

    end #begin-resuce
  end #task
end #namespace

我遇到的问题是这需要几分钟才能输入 10 万多个条目。我想找到一种更有效的方法来更新我的数据库。理想情况下,这将保持独立于数据库类型,但如果不是,我的生产服务器将在 MySQL 上运行。

感谢您的任何见解。

最佳答案

您是否尝试过使用 AR Extensions批量导入?当您将 1000 行插入数据库时​​,您会获得令人印象深刻的性能改进。访问他们的 website更多细节。

有关更多信息,请参阅这些示例

Usage Example 1

Usage Example 2

Usage Example 3

关于ruby-on-rails - 高效的批量更新 rails 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2284962/

相关文章:

c# - Entity Framework 映射 API 引用错误

ruby-on-rails - Rails 4 迁移:Mysql2::Error:列 'xxxx' 的数据太长

ruby-on-rails - 只进行一次迁移

mysql - 来自 MySQL 的 ActiveRecord/Rails 查询数据排序问题 - SQLite 中没有问题

ruby-on-rails - 设计错误未定义方法 `email'

ruby-on-rails - 如何为以下查询编写 Rspec 规范

ruby-on-rails - nokogiri 无法安装 osx

sql - Rails/ActiveRecord 按特定值排序

c# - 百万插入 : SqlBulkCopy timeout

sql-server - Windows 7 上的 SQL Server 批量插入问题