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

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

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

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

最小到可能为零的Donwtime程序

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

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

     Video.first.picture.url 

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

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

  6. 重新启动后,您的所有资产都将通过云提供,并且您的模型中不需要任何迁移或多个上传程序。

  7. (基于@Frederick Cheung的评论):使用s3cmd(或类似的东西) rsync或将资产文件夹从文件系统sync到S3,以考虑在步骤2和5之间上传的资产(如果有的话)。

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

我尝试以下步骤:

  1. 将上传器中的存储更改为:雾或您想要使用的内容
  2. 编写像rails g migration MigrateFiles这样的rails g migration MigrateFiles ,让carrierwave获取当前文件,处理它们并将它们上传到云端。

如果您的模型如下所示:

 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下载每个图像,因为您为附件指定了一个远程URL(当前位置,如http://test.com/images/1.jpg ),并将其保存到云中,因为您在上传器中更改了它。

编辑:

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

当我们使用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变量更改上传器提供程序。 祝好运!

我已经使用s3cmd将Carrier wave文件迁移到Amazon s3并且它可以工作。

以下是要遵循的步骤:

  1. 将上传器的存储类型更改为雾。
  2. 如果您还没有,请在Amazon s3上创建一个存储桶 。
  3. 在远程服务器sudo apt-get install s3cmd
  4. 配置s3cmd s3cmd --configure 。 您需要在此处输入由亚马逊提供的公钥和密钥。
  5. 通过此命令s3cmd sync /path_to_your_files ://bucket_name/文件s3cmd sync /path_to_your_files ://bucket_name/
  6. 设置此标志--acl-public将文件上传为公共文件并避免权限问题。
  7. 重启你的服务器

笔记:

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