LoginSignup
9
7

More than 5 years have passed since last update.

Rails / 定期的に Amazon S3 のファイルを読み込んで処理するRakeタスク

Last updated at Posted at 2015-02-10

ブログを更新しました。元の記事はコチラ


Amazon S3にファイルが入っていて、
Railsのrakeタスクかなんかで定期的に処理を走らせるみたいな。
そんな事あんまりないかもしれないけど、今回必要だったのでメモ。

  
s3-rake

例えばこんな状況

  • 営業が .csv を Amazon S3 にアップロード
  • 定期的にRakeタスクを実行してDBに取り込む

S3はこんな構成になっているとする。
my_bucketの中身を読み込みたい。

  • other_bucket
  • my_bucket
    • data
      • record-2015-02-09
        • 01.csv
        • 02.csv
      • record-2015-02-10
        • 01.csv
        • 02.csv

他の誰かからS3に安全にアップロードしてもらう方法はこちら。
Developerではない人にはFTPクライアント使ってもらいます。
http://www.workabroad.jp/posts/2131

Gem

aws/aws-sdk-ruby

Gemfile
gem 'aws-sdk', '~> 2'

S3のデータを読み込む

S3KEY / S3SECRET / S3REGION は環境変数に入れておいてください。
「あるBucketの中のフォルダの中のファイルたち」みたいなのは prefix をつかって指定します。

my_bucket/data/record-2015-02-10 なら
prefix: "data/record-2015-02-10" のように。

/lib/tasks/content.rake

require 'aws-sdk'
def get_records(date)

    bucket = "my_bucket"

    records = []

    Aws.config.update(
      access_key_id: ENV['S3KEY'],
      secret_access_key: ENV['S3SECRET'],
      region: ENV['S3REGION']
    )
    s3 = Aws::S3::Client.new

    s3.list_objects(bucket: bucket, prefix: "data/record-#{date}").contents.each do |obj|
        puts obj.key
        # get_object.body returns StringIO object
        # http://docs.ruby-lang.org/ja/2.0.0/class/StringIO.html
        text = s3.get_object(bucket: bucket, key: obj.key).body.read
        records |= text
    end

    # remove nil
    records.compact!
end

AWSの設定

IAM
list_objectsget_object を使うので、
実行できる権限がないと Access Denied と言われてしまう。
IAMで設定しておきましょう。

  
CORS
コメント頂きました。CORS必要ないです。

my_bucket の CORS configurationも設定が必要。
S3 Management Console

AllowedOrigin が * になってますが適切なものに変えてください。

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

Rakeタスク

これは普通のrakeタスク。
実行時にオプション渡せるようにもしてる。
こんな感じ。

rake content:create["2015-02-09"]

  
何も渡さなければ今日の日付がついたフォルダをS3から探して何かする、と。
HerokuのSchedulerとかで定期的に実行する場合はオプションなしで指定しておけば便利。

/lib/tasks/content.rake

namespace :content do
  desc "Create contents from files in Amazon S3"

  task :create, "date"

  task create: :environment do |task, options|
    if options.date.present?
        date = options.date
    else
        date = Time.current.in_time_zone('Tokyo').strftime('%Y-%m-%d')
    end

    puts date
    records = get_records(date)

    records.each do |record|
      # do something
    end
  end
end

以上です。
自動化するといろいろ楽ですね。

参考

AWS | Tools

Class: Aws::S3::Client — AWS SDK for Ruby V2

Class: AWS.Config — AWS SDK for JavaScript

AWS SDK for Ruby(V2)を利用して、Amazon S3を操作する - Qiita

aws/aws-sdk-ruby

http://workabroad.jp/posts/2133

9
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
7