Ruby on rails Rails-Roo“;“文件不存在”;使用延迟作业时出错
我正在使用RooGem导入Excel文件、CSV文件等 这段代码在a)我本地的盒子上运行得很好,有没有延迟的工作,b)在Heroku上运行得很好,没有延迟的工作。不幸的是,在Heroku上运行时,如果我使用延迟作业,它将失败 详情如下 控制器:Ruby on rails Rails-Roo“;“文件不存在”;使用延迟作业时出错,ruby-on-rails,heroku,delayed-job,import-from-excel,Ruby On Rails,Heroku,Delayed Job,Import From Excel,我正在使用RooGem导入Excel文件、CSV文件等 这段代码在a)我本地的盒子上运行得很好,有没有延迟的工作,b)在Heroku上运行得很好,没有延迟的工作。不幸的是,在Heroku上运行时,如果我使用延迟作业,它将失败 详情如下 控制器: def importdo fileimport = Fileimport.new fileimport.file_name = params[:file].original_filename fileimport.file_path = pa
def importdo
fileimport = Fileimport.new
fileimport.file_name = params[:file].original_filename
fileimport.file_path = params[:file].path
fileimport.save
fileimportid = fileimport.id
Building.delay.import(fileimportid)
redirect_to buildings_path, notice: "Buildings import started . . . you will receive an email upon completion."
end
fileimport
只是我用来跟踪文件名和文件路径的一个表(我尝试将它们作为参数传递,但DelayedJob在尝试将哈希转换为YAML时总是会遇到问题,所以我只传递记录ID)。这也给了我在表中跟踪导入的好处
以下是我的导入类方法:
def self.import(fileimportid)
fileimport = Fileimport.find(fileimportid)
file_name = fileimport.file_name
file_path = fileimport.file_path
newcount = 0
updatecount = 0
updating = false
Building.acts_as_gmappable :process_geocoding => false
spreadsheet = open_spreadsheet(file_name, file_path)
header = spreadsheet.row(1)
(2..spreadsheet.last_row).each do |i|
row = Hash[[header, spreadsheet.row(i)].transpose]
if zip = row["zip"].to_i.to_s
if zip.length > 5
zip = zip.first(5)
end
else
raise "zip not valid"
end
if building = find_by_address_and_zip(row["address"], zip)
updating = true
else
building = Building.new
end
#building.name = row["name"]
building.zip = zip
building.address = row["address"]
building.city = row["city"]
building.save!
if updating
updatecount += 1
else
newcount += 1
end
updating=false
end
Building.acts_as_gmappable :process_geocoding => true
subject = "Your Building Import Completed Successfully!"
body = "Your Building Import completed successfully!\n\n" + newcount.to_s + " buildings were created.\n" + updatecount.to_s + " buildings were updated."
require 'rest_client'
RestClient.post MAILGUN_API_URL+"/messages", :from => "obfuscated", :to => "obfuscated", :subject => subject, :text => body
end
def self.open_spreadsheet(file_name, file_path)
case File.extname(file_name)
when ".csv" then Roo::Csv.new(file_path, nil, :ignore)
when ".xls" then Roo::Excel.new(file_path, nil, :ignore)
when ".xlsx" then Roo::Excelx.new(file_path, nil, :ignore)
else
raise "Unknown file type: #{file_name}"
end
end
这是我的文件输入表格:
<% provide(:title, 'Import Buildings') %>
<div class="row">
<aside class="span4">
<section>
<h1>
Import Products
</h1>
<%= form_tag importdo_buildings_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
</section>
</aside>
</div>
不管怎样,就像我说的,在我的盒子上效果很好(无论有没有延迟的工作)。只在Heroku上工作,没有延迟作业(即,我必须取出。延迟)。以下是我收到的具体错误(错误通过电子邮件发送给我,我使用观察员检查延迟的时间::Job保存记录并检查最后一个错误):
我最初的想法是,它只是一个Heroku文件系统的东西,但我认为如果没有延迟的工作,它也不会工作。我的另一个想法是,因为它是异步的,所以可能是一个时间问题(可能临时文件还不存在或者不再存在)
非常感谢您的任何想法。您最初的想法是正确的。。你的问题背后是Heroku文件系统。即只读规则 当您将文件发送到Heroku时,它存储在临时文件夹中,仅在这一请求期间可用。它不会延迟工作,因为您在一个请求期间完成工作,并且文件可用 但当请求结束时,延迟的_作业将单独完成,因此文件将被删除
最简单的解决方案是将文件放在一些云存储中(我使用S3和carrierwave来实现这一目的。我没有在Heroku上使用DJ,但我使用了Resque——我必须确保工作人员已启动。您是否已启动dynos来处理延迟的工作?我正在使用workless,而DelayedJob正在运行,因为这是导致我出错的原因。我可以尝试关闭workless,然后让工人准备好了,以防时机不成熟。
resources :buildings do
collection { post :importdo }
end
file /tmp/RackMultipart20130516-13-7li3o7 does not exist
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/excel.rb:26:in `block in initialize'
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/generic_spreadsheet.rb:579:in `block in make_tmpdir'
/app/vendor/ruby-1.9.3/lib/ruby/1.9.1/tmpdir.rb:83:in `mktmpdir'
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/generic_spreadsheet.rb:578:in `make_tmpdir'
/app/vendor/bundle/ruby/1.9.1/gems/roo-1.11.2/lib/roo/excel.rb:19:in `initialize'
/app/app/models/building.rb:84:in `new'
/app/app/models/building.rb:84:in `open_spreadsheet'
/app/app/models/building.rb:39:in `import'