如何将CarrierWave文件迁移到新的存储机制?

时间:2014-07-12 21:04:58

标签: ruby-on-rails activerecord carrierwave

我有一个Ruby on Rails站点,其中模型使用CarrierWave进行文件处理,目前使用的是本地存储。我想开始使用云存储,我需要将现有的本地文件迁移到云端。我想知道是否有人可以指出这样做的方法?

使用模型属性的加分点,允许我在后台逐行执行此操作,而不会中断我的网站以延长停机时间(换句话说,某些模型行仍然具有本地存储,而其他模型行使用云存储)。

我的第一直觉是为每个使用云存储的模型创建一个新的上传器,所以我在每个模型上有两个上传器,然后将文件从一个传输到另一个,设置一个属性来指示应该使用哪个文件,直到他们全部转移,然后删除旧的上传者。这似乎有点过分。

4 个答案:

答案 0 :(得分:8)

最小可能零点Donwtime程序

在我看来,通过几乎没有停机时间来实现您想要的最简单,最快捷的方法是:(我将假设您将使用AWS云,但类似的程序适用于任何云服务)

  1. 找出并设置资产存储桶,存储桶策略等,以使资产可公开访问。
  2. 使用s3cmd(用于与S3交互的命令行工具)或GUI应用程序,将整个资产文件夹从文件系统复制到S3中的相应文件夹。
  3. 在您的应用中,设置carrierwave并更新:fog存储的模型/上传器。
  4. 请勿重新启动您的应用程序。而是调出rails控制台和模型,检查新资产URL是否正确且可按计划访问。例如,对于带有图片资源的视频模型,您可以这样检查:

    Video.first.picture.url
    

    这将根据更新的设置为您提供完整的云URL。复制URL并粘贴到浏览器中,以确保您可以正常使用。

  5. 如果这适用于每个具有资产的模型的至少一个实例,则可以重新启动应用程序。

  6. 重启后,您的所有资产都是通过云提供的,您的模型中不需要任何迁移或多个上传者。

  7. (基于@Frederick Cheung的评论):使用s3cmd(或类似的)rsyncsync资源文件夹从文件系统到S3来计算资产在步骤2和5之间上传的内容,如果有的话。

  8. PS:如果您需要帮助为云存储设置carrierwave,请告诉我们。

答案 1 :(得分:2)

我会尝试以下步骤:

  1. 将上传者的存储空间更改为:雾或您想要使用的内容
  2. 编写像rails g migration MigrateFiles这样的迁移,让carrierwave获取当前文件,处理它们并将它们上传到云端。
  3. 如果您的模型如下所示:

    class Video
      mount_uploader :attachment, VideoUploader
    end
    

    迁移将如下所示:

    @videos = Video.all
    @videos.each do |video|
      video.remote_attachment_url = video.attachment_url
      video.save
    end
    

    如果执行此迁移,则应执行以下操作:

    Carrierwave会下载每张图片,因为您为附件指定了一个远程网址(当前位置,如http://test.com/images/1.jpg)并将其保存到云中,因为您在上传器中对其进行了更改。

    修改

    由于San指出这不会直接起作用,你应该首先创建一个额外的列,运行迁移以将所有视频中的当前attachment_urls复制到该列,然后更改上传器并使用复制运行上述迁移在新专栏中的网址。使用另一个迁移只需再次删除该列。不是那么简单干净,而是在几分钟内完成。

答案 2 :(得分:1)

当我们使用Heroku时,大多数人建议使用cloudinary。免费且简单的设置。 我的情况是当我们使用cloudinary服务时,由于某些原因需要移入aws S3。

这就是我对上传者的所作所为:

class AvatarUploader < CarrierWave::Uploader::Base

  def self.set_storage
    if ENV['UPLOADER_SERVICE'] == 'aws'
      :fog
    else
      nil
    end
  end

  if ENV['UPLOADER_SERVICE'] == 'aws'
     include CarrierWave::MiniMagick
  else
     include Cloudinary::CarrierWave
  end

  storage set_storage
end

另外,设置rake任务:

task :migrate_cloudinary_to_aws do
    profile_image_old_url = []
    Profile.where("picture IS NOT NULL").each do |profile_image|
      profile_image_old_url << profile_image
    end

   ENV['UPLOADER_SERVICE'] = 'aws'
   load("#{Rails.root}/app/uploaders/avatar_uploader.rb")

   Profile.where("picture IS NOT NULL OR cover IS NOT NULL").each do |profile_image|
     old_profile_image = profile_image_old_url.detect { |image| image.id == profile_image.id }
     profile_image.remote_picture_url = old_profile_image.picture.url
     profile_image.save
   end
end

诀窍是如何通过env变量更改上传器提供程序。祝你好运!

答案 3 :(得分:0)

我已使用s3cmd将载波文件迁移到Amazon s3,并且可以使用。

以下是要执行的步骤:

  1. 将上传器的存储类型更改为fog。
  2. 如果您尚未在Amazon s3上创建bucket
  3. 在远程服务器sudo apt-get install s3cmd上安装s3cmd
  4. 配置s3cmd s3cmd --configure。 您需要在此处输入由Amazon提供的公共密钥和秘密密钥。
  5. 通过此命令s3cmd sync /path_to_your_files ://bucket_name/
  6. 同步文件
  7. 设置此标志--acl-public以将文件上传为公共文件,并避免权限问题。
  8. 重新启动服务器

注释:

sync将不会重复您的记录。它将首先检查文件是否存在于远程服务器上。