我有一个rake任务,使用paperclip从表格网站加载汽车图像。存储在数据库中的图像作为远程链接。
这是我的代码,我使用的是ruby 1.8.7,rails 2.3.8和DB mysql。
namespace :db do
task :load_photo => :environment do
require 'rubygems'
require 'open-uri'
require 'net/http'
require 'paperclip'
begin
images =Website.find(:all,:conditions=>["image_url is not null"])
images.each do |photo|
url = URI.parse(photo.image_url)
Net::HTTP.start(url.host, url.port) do |http|
if http.head(url.request_uri).code == "200"
Car.update_attribute(:photo,open(url))
end
end
end
rescue Exception => e
end
end
end
通过db:load_photo在rake任务上运行。在我的表(网站)有60,000行。 Rake任务仅运行10000行,执行因“执行过期”错误消息而终止。
任何人都可以帮我解决这个问题吗?
提前致谢。
答案 0 :(得分:2)
您可能会发现批量运行它更有效,活动记录有一个find_in_batches
方法,可以停止一次将所有记录加载到内存中。
http://ryandaigle.com/articles/2009/2/23/what-s-new-in-edge-rails-batched-find
您可以将代码更改为:
namespace :db do
task :load_photo => :environment do
require 'rubygems'
require 'open-uri'
require 'net/http'
require 'paperclip'
Website.find_in_batches(:conditions=>["image_url is not null"]) do |websites|
websites.each do |website|
begin
url = URI.parse(website.image_url)
Net::HTTP.start(url.host, url.port) do |http|
if http.head(url.request_uri).code == "200"
Car.update_attribute(:photo,open(url))
end
end
rescue Exception => e
end
end
end
end
end
答案 1 :(得分:1)
我只能猜测,但看起来你正在向服务器发出一点DoS攻击,你正在从中提取图像。
您可以尝试在顺序请求之间稍微延迟播放(例如“睡眠1”)。
此外,如果您的“执行过期”是Timeout :: Error异常,那么您无法用
来捕获它rescue Exception => e
因为Timeout :: Error不是StandardError的子类,所以它是Interrupt类的子类。你必须明确地捕捉它,如下:
rescue Timeout::Error => e