2016-02-25 81 views
0

我使用Amazon boto v2.38编写python脚本来访问我的S3存储桶。在s3中更新元数据

我想更新我的存储桶中的文件(我知道它在S3中被称为“key”)。路径是MyBucket/myfile/demo.txt。此外,我还想更新名为“name”的元数据。这里是我试过的代码:

# connect to key 
conn = boto.connect_s3() 
bucket = conn.get_bucket("MyBucket") 

my_key = Key(bucket) 
my_key.key = "myfile/demo.txt" 

# if key exists, then update the file & its metadata 
if my_key.exists(): 
    new_meta_data = {"name": "xyz"} 
    # update metadata 
    my_key.copy("MyBucket", my_key.name, new_meta_data, preserve_acl=True) 
    # update file content in S3 by using the local file demo.txt 
    my_key.set_contents_from_filename("demo.txt") 

但是,它不工作......我没有看到元数据得到更新。为什么?

回答

0

下面的代码改变键的元数据中boto3

import boto3 as aws 

s3 = aws.resource('s3') 
obj = s3.Bucket('MyBucket').Object('objectKey') 
obj.put(Metadata={'name':'newName'} 

According to the docsset_metadata必须使用。我已经测试它和foloowing代码与boto2,并改变meatadata:

import boto as aws 

cx=aws.connect_s3() 
bucket=cx.get_bucket('MyBucket') 
obj=bucket.get_key('objectKey') 
obj.set_metadata('name', 'newName') 
+0

我想'set_metadata(“名”,“了newName”)'我的项目开始时,它没有工作,然后我改为使用我的代码中显示的'my_key.copy(...)'。 –

+0

你可以试试boto3吗?我已经测试了我建议的代码。 – jruizaranguren

+0

我们的项目使用boto2,这是我的问题的先决条件。但是谢谢你的帮助。 –

2

您只需更新密钥的本地元数据,然后进行文件更新:

import boto 

conn = boto.connect_s3() 
bucket = conn.get_bucket("MyBucket") 
key = bucket.get_key('myfile/demo.txt') 
key.set_metadata('name', 'xyz') 
key.set_contents_from_filename('demo.txt') 

现在name应该出现S3中的元数据。但请注意,当您这样做时ACL可能会发生变化。

它也可以用key.set_remote_metadata()完成。这并不是要求你更新的关键内容(但你可以的,如果你想):

conn = boto.connect_s3() 
bucket = conn.get_bucket('MyBucket') 
key = bucket.get_key('myfile/demo.txt') 
key.set_remote_metadata({'name': 'xyz'}, {}, True) 
+0

这是正确的答案。 set_metadata设置当前在内存中的对象(以python的形式)的数据,并且只有在对象被再次推送时才会应用于对象存储。 set_remote_metadata直接在对象存储上设置元数据,而不需要再次推送对象,但它有一个奇怪的未记录语法(set_remote_meatadat(metadata_dict,{},True) 关于该主题的好博客文章:http:///eddwardo.github.io/2015/07/01/boto-s3-and-remote-metadata/ –

+0

另请注意,set_remote_metadata完全按照字典中提供的方式设置元数据,并将删除以前的键/值。您无法使用它更新元数据,您需要设置所有的键/值。 –

0

使用Boto3,要小心,如果使用“put_object”与元数据,这会改变你的实际metadatas,如果你想创建具有metadatas对象,然后添加元数据或更新现有的元数据,使用下面:

import sys 
import os 
import boto3 
from boto3 import client 

param_1= sys.argv[1] 
param_2= sys.argv[2] 
param_3= sys.argv[3] 
param_4= sys.argv[4] 
param_5= sys.argv[5] 

objectNMAE='THIEF.jpg' 

s3ressource = client(
    service_name='s3', 
    endpoint_url= param_3, 
    aws_access_key_id= param_1, 
    aws_secret_access_key=param_2, 
    use_ssl=True, 
    ) 

def createmetdata(bucketname,objectname): 
    s3ressource.upload_file(objectname, bucketname, objectname, ExtraArgs={"Metadata": {"metadata1":"ImageName","metadata2":"ImagePROPERTIES" ,"metadata3":"ImageCREATIONDATE"}}) 

def ADDmetadata(bucketname,objectname): 
    s3_object = s3ressource.get_object(Bucket=bucketname, Key=objectname) 
    k = s3ressource.head_object(Bucket = bucketname, Key = objectname) 
    m = k["Metadata"] 
    m["new_metadata"] = "ImageNEWMETADATA" 
    s3ressource.copy_object(Bucket = bucketname, Key = objectname, CopySource = bucketname + '/' + objectname, Metadata = m, MetadataDirective='REPLACE') 

def CHANGEmetadata(bucketname,objectname): 
    s3_object = s3ressource.get_object(Bucket=bucketname, Key=objectname) 
    k = s3ressource.head_object(Bucket = bucketname, Key = objectname) 
    m = k["Metadata"] 
    m.update({'metadata3':'ImageCREATIONDATEEEEEEEEEEEEEEEEEEEEEEEEEE'}) 
    s3ressource.copy_object(Bucket = bucketname, Key = objectname, CopySource = bucketname + '/' + objectname, Metadata = m, MetadataDirective='REPLACE') 

def readmetadata (bucketname,objectname): 
    ALLDATAOFOBJECT = s3ressource.get_object(Bucket=bucketname, Key=objectname) 
    ALLDATAOFOBJECTMETADATA=ALLDATAOFOBJECT['Metadata'] 
    print ALLDATAOFOBJECTMETADATA 

createmetdata(param_4,objectNMAE) 
readmetadata(param_4,objectNMAE) 
ADDmetadata(param_4,objectNMAE) 
readmetadata(param_4,objectNMAE) 
CHANGEmetadata(param_4,objectNMAE) 
readmetadata(param_4,objectNMAE)