2012-02-14 2 views
11

S3에서 수백 또는 수천 개의 개체에 대해 일부 메타 데이터 (Content-Type)를 변경해야합니다. 루비로이 작업을 수행하는 좋은 방법은 무엇입니까? 지금까지는 fog.io으로 메타 데이터 만 저장할 방법이 없다는 것을 알게되면 전체 개체를 다시 저장해야합니다. the official sdk library을 사용하는 것 같이 보인다면이 하나의 작업만을위한 래퍼 환경을 필요로합니다.루비를 사용하여 S3 객체의 메타 데이터를 어떻게 업데이트합니까?

답변

6

맞습니다. 공식 SDK를 사용하면 개체 메타 데이터를 다시 업로드하지 않고 수정할 수 있습니다. 파일의 내용은 copy the object이지만 서버에 있으므로 파일을 다운로드하고 다시 업로드 할 필요가 없습니다.

래퍼는 미래의 독자

bucket.objects.each do |object| 
    object.metadata['content-type'] = 'application/json' 
end 
+0

자세한 내용은 http://groups.google.com/group/ruby-fog/browse_thread/thread/e632fc61405bf04c –

+2

에서 x-amz-meta- prefix가있는 메타 데이터 만 추가됩니다. 일반 Content-Type 메타 데이터를 추가하는 방법은 무엇입니까? – serengeti12

4

같은 것을 구현하기 쉬운 것입니다, 여기에 루비 AWS-SDK의 V1을 사용하여 물건을 변경하는 완전한 샘플입니다 (또한 AWS-SDK v2의이 Gist 참조 예제) 다음 V2의 API에서

# Using v1 of Ruby aws-sdk as currently v2 seems not able to do this (broken?). 
require 'aws-sdk-v1' 

key = YOUR_AWS_KEY 
secret = YOUR_AWS_SECRET 
region = YOUR_AWS_REGION 

AWS.config(access_key_id: key, secret_access_key: secret, region: region) 
s3 = AWS::S3.new 
bucket = s3.buckets[bucket_name] 
bucket.objects.with_prefix('images/').each do |obj| 
    puts obj.key 
    # Add metadata: {} to next line for more metadata. 
    obj.copy_from(obj.key, content_type: obj.content_type, cache_control: 'max-age=1576800000', acl: :public_read) 
end 
+0

귀하의 요점은 v2 샘플이 작동하지 않는 것 같으며 SDK의 버그 일 수 있다고 제안합니다. 아직 해결하지 않았습니까? – scottb

+0

Nope. 그냥 v2의 최신 버전으로 요점을 시도하십시오 :) – joost

+0

v2 버전이 나에게 적합하지 않습니다. 나는 나의 해결책으로 요점을 언급했다 (각 파일을 다시로드). –

5

, 당신은 S3에서 다운로드하지 않고 객체의 메타 데이터를 업데이트 할 :metadata:metadata_directive => 'REPLACE' 옵션 Object#copy_from() 또는 Object.copy_to()를 사용할 수 있습니다. 기본적으로 AWS가 복사 작업 복사하므로 메타 데이터와 함께 제공되는 :metadata 무시되므로

Aws::S3::Errors::InvalidRequest: This copy request is illegal because it is trying to copy an object to itself without changing the object's metadata, storage class, website redirect location or encryption attributes.

이것은 :

Joost's gist의 코드는 오류를 던진다. 메타 데이터를 현재 위치에서 업데이트하려면 :metadata_directive => 'REPLACE' 옵션을 설정해야합니다.

require 'aws-sdk' 

# S3 setup boilerplate 
client = Aws::S3::Client.new(
    :region => 'us-east-1', 
    :access_key_id => ENV['AWS_ACCESS_KEY'], 
    :secret_access_key => ENV['AWS_SECRET_KEY'], 
) 
s3 = Aws::S3::Resource.new(:client => client) 

# Get an object reference 
object = s3.bucket('my-bucket-name').object('my-object/key') 

# Create our new metadata hash. This can be any hash; in this example we update 
# existing metadata with a new key-value pair. 
new_metadata = object.metadata.merge('MY_NEW_KEY' => 'MY_NEW_VALUE') 

# Use the copy operation to replace our metadata 
object.copy_to(object, 
    :metadata => new_metadata, 

    # IMPORTANT: normally S3 copies the metadata along with the object. 
    # we must supply this directive to replace the existing metadata with 
    # the values we supply 
    :metadata_directive => "REPLACE", 
) 

쉽게 재사용 :

def update_metadata(s3_object, new_metadata = {}) 
    s3_object.copy_to(s3_object, 
    :metadata => new_metadata 
    :metadata_directive => "REPLACE" 
) 
end 
+0

캐시 제어를 사용하려면 object.copy_to (object, cache_control : 'public, max-age = 333333', metadata_directive : 'REPLACE')를 사용하십시오. –

관련 문제