【问题标题】:Uploading thousands of images with Paperclip to S3使用 Paperclip 将数千张图像上传到 S3
【发布时间】:2011-09-21 15:05:17
【问题描述】:

我有大约 16,000 张图片正在尝试上传到亚马逊。现在,它们在我的本地文件系统上。我想使用 Paperclip 将它们上传到 S3,但我不想先将它们上传到我的服务器。我正在使用 Heroku,它们限制了 slug 的大小。

有没有办法使用 rake 任务通过 Paperclip 将图像直接从我的本地文件系统上传到 S3?

【问题讨论】:

    标签: ruby-on-rails amazon-s3 paperclip


    【解决方案1】:

    您可以将您的应用配置为在开发中使用 Amazon S3 进行回形针存储 (see my example) 并使用 rake 任务上传文件,如下所示:

    假设你的图片文件夹在your_app_folder/public/images,你可以创建一个类似的rake任务。

    namespace :images do
      desc "Upload images."
      task :create => :environment do
        @images = Dir["#{RAILS_ROOT}/public/images/*.*"]
        for image in @images
          MyModel.create(:image => File.open(image))
        end
      end
    end
    

    【讨论】:

    • 对。所以这正是我所做的,但这需要很长时间(每张图像> 1秒)。我也有回形针在文件名中使用图像ID的问题。因此,即使我运行您提到的 rake 任务,生产中的 id 也不会与开发中的 id 匹配。
    • 在这种情况下,您可以使用文件上传器将文件上传到 Dropbox(甚至是临时 s3 存储桶)之类的东西,然后从您的 heroku 应用程序运行这个 rake 任务(传递远程链接)将它们移动到您的回形针桶/将它们与您的模型相关联。
    • 谢谢约翰尼。我们也试过了,但在使用 heroku 通过 FTP 访问文件时遇到了麻烦。最终上传到本地回形针,然后将所有图像 url 输出到文本文件。然后我们将文本文件投入生产并读入所有图像 url。可怕的黑客,但它的工作。感谢您的建议。
    【解决方案2】:

    是的。我在我的第一个个人 Rails 项目中做了类似的事情。这是以前的 SO 问题 (Paperclip S3 download remote images),其答案链接到我很久以前找到答案的地方 (http://trevorturk.com/2008/12/11/easy-upload-via-url-with-paperclip/)。

    【讨论】:

      【解决方案3】:

      很好的答案约翰尼格拉斯和很好的问题克里斯。我的本地机器、Heroku、回形针和 s3 上有几百个 tif 文件。一些 tiff 文件大于 100MB,因此让 heroku 注意到长期需要延迟的工作和一些额外的工作。由于这主要是一个一次性的批处理过程(5 个不同的图像形式从每个创建 5 次上传),因此 rake 任务的想法非常适合。如果有帮助,这里是我创建的 rake 任务,假设像 Johnny 写的那样,您的开发数据库具有当前数据(使用 pg 备份获取新的 id 集)并连接到 S3。

      我有一个名为“项目”的模型,带有附件“图像”。我想检查现有项目是否已经有图像,如果没有,则上传新的。效果是镜像一个源文件目录。好的扩展可能是检查日期并查看本地 tif 是否更新。

      # lib/image_management.rake
      namespace :images do
        desc 'upload images through paperclip with postprocessing'
        task :create => :environment do
      
          directory = "/Volumes/data/historicus/_projects/deeplandscapes/library/tifs/*.tif"
          images = Dir[directory]
      
          puts "\n\nProcessing #{ images.length } images in #{directory}..."
      
          items_with_errors = []
          items_updated = []
          items_skipped = []
      
          images.each do |image|
          # find the needed record
            image_basename = File.basename(image)
            id = image_basename.gsub("it_", "").gsub(".tif", "").to_i
            if id > 0
              item = Item.find(id) rescue nil
              # check if it has an image already
              if item
                unless item.image.exists?
                  # create the image
                  success = item.update_attributes(:image => File.open(image))
                  if success
                    items_updated << item
                    print ' u '
                  else
                    items_with_errors << item
                    print ' e '
                  end
                else
                  items_skipped << item
                  print ' s '
                end
              else
                print "[#{id}] "
              end
            else
              print " [no id for #{image_basename}] "    
            end
          end
          unless items_with_errors.empty?
            puts "\n\nThe following items had errors: "
            items_with_errors.each do |error_image|
              puts "#{error_image.id}: #{error_image.errors.full_messages}"
            end
          end
      
          puts "\n\nUpdated #{items_updated.length} items."
          puts "Skipped #{items_skipped.length} items."
          puts "Update complete.\n"
      
        end
      end
      

      【讨论】:

        猜你喜欢
        • 2023-03-29
        • 1970-01-01
        • 2014-01-18
        • 2015-10-01
        • 2021-04-07
        • 2019-07-14
        • 1970-01-01
        • 2011-01-14
        • 2011-06-29
        相关资源
        最近更新 更多