2016-03-04 7 views
13

S3 बाल्टी में सबफ़ोल्डर नाम प्राप्त कर रहा है boto3 का उपयोग करना, मैं अपने एडब्ल्यूएस S3 बाल्टी का उपयोग कर सकते उदाहरण 1456753904534। मुझे इन उप-फ़ोल्डर्स का नाम किसी अन्य नौकरी के लिए जानना है जो मुझे लगता है और मुझे आश्चर्य है कि क्या मुझे boto3 मेरे लिए उनको पुनर्प्राप्त कर सकता है।से boto3

तो मैं करने की कोशिश की:

objs = bucket.meta.client.list_objects(Bucket='my-bucket-name') 

जो एक शब्दकोश, जिसका कुंजी 'सामग्री' मुझे दूसरे स्तर टाइमस्टैम्प निर्देशिका के बजाय सभी तृतीय-स्तर फ़ाइलों देता है देता है, वास्तव में मैं चीजों को शामिल करते हुए एक सूची प्राप्त के रूप में

{u'ETag ':' 'ETag "', u'Key ': प्रथम स्तर/1456753904534/अंशकालिक 00014', u'LastModified ': datetime.datetime (2016 2, 29 , 13, 52, 24, tzinfo = tzutc()),
u'Owner ': {u'DisplayName': 'owner', u'ID ': 'आईडी'},
u'Size ': आकार, u'StorageClass': 'storageclass'}

आप देख सकते हैं, जब तक मैं चाहता हूँ कि इस मामले part-00014 में विशिष्ट फ़ाइलों, प्राप्त किए गए हैं अकेले निर्देशिका का नाम प्राप्त करने के लिए। सिद्धांत रूप में मैं सभी पथों से निर्देशिका नाम को हटा सकता हूं लेकिन दूसरे स्तर को पाने के लिए यह तीसरे स्तर पर सबकुछ पुनः प्राप्त करने के लिए बदसूरत और महंगा है!

मैं भी कुछ here सूचना दी की कोशिश की:

for o in bucket.objects.filter(Delimiter='/'): 
    print(o.key) 

लेकिन मैं फ़ोल्डरों वांछित स्तर पर नहीं मिलता है।

क्या इसे हल करने का कोई तरीका है?

+0

तो तुम कह रहे हो कि [इस] (https://github.com/बोटो/boto3/मुद्दों/134 # मुद्दा टिप्पणी-116766812) काम नहीं करता है? क्या आप पोस्ट कर सकते हैं जब आप इसे चलाते हैं? –

+1

@ जोर्डन फिलिप्स मैंने आपके द्वारा भेजे गए लिंक की पहली पंक्तियों को आजमाया है, जिसे मैंने यहां चिपकाया है, और मुझे टेक्स्ट फाइलें बाल्टी के पहले स्तर पर और कोई फ़ोल्डर्स नहीं मिलती हैं। –

+0

@mar tin क्या आपने कभी इस मुद्दे को हल किया था। मुझे एक समान दुविधा का सामना करना पड़ रहा है जहां मुझे हर बाल्टी सबफ़ोल्डर में पहला तत्व चाहिए। –

उत्तर

8

S3 एक वस्तु की जगह है, यह वास्तविक निर्देशिका संरचना नहीं है। "/" बल्कि कॉस्मेटिक है। एक कारण है कि लोग निर्देशिका संरचना चाहते हैं, क्योंकि वे एप्लिकेशन में पेड़ को बनाए/प्रतिरक्षा/जोड़ सकते हैं। एस 3 के लिए, आप इस तरह की संरचना का सूचकांक या खोज टैग के प्रकार के रूप में व्यवहार करते हैं।

एस 3 में ऑब्जेक्ट में हेरफेर करने के लिए, आपको boto3.client या boto3.resource की आवश्यकता है, उदा। सभी वस्तु

import boto3 
s3 = boto3.client("s3") 
all_objects = s3.list_objects(Bucket = 'my-bucket-name') 

http://boto3.readthedocs.org/en/latest/reference/services/s3.html#S3.Client.list_objects

को सूचीबद्ध करने के boto3 के बारे में एक अनुस्मारक: boto3.resource एक अच्छा उच्च स्तर एपीआई है। Boto3.client बनाम boto3.resource का उपयोग कर पेशेवर और विपक्ष है। यदि आप आंतरिक साझा लाइब्रेरी विकसित करते हैं, तो boto3.resource का उपयोग करके आपको संसाधनों पर ब्लैकबॉक्स परत मिल जाएगी।

+1

यह मुझे वही परिणाम देता है जो मुझे प्रश्न में मेरे प्रयास के साथ मिलता है। मुझे लगता है कि मुझे लौटाई गई वस्तुओं से सभी चाबियाँ पकड़कर और फ़ोल्डर नाम प्राप्त करने के लिए स्ट्रिंग को विभाजित करके कठिन तरीके से हल करना होगा। –

+1

@ मार्टिना: एक आलसी पायथन विभाजित करें और सूची के अंदर अंतिम डेटा उठाएं उदा। फ़ाइल नाम = keyname.split ("/") [- 1] – mootmoot

+1

@martin 'directory_name = os.path.dirname (निर्देशिका/पथ/और/filename.txt) 'और' file_name = os.path.basename (निर्देशिका/पथ/और/filename.txt) ' – jkdev

1

सबसे पहले, एस 3 में कोई वास्तविक फ़ोल्डर अवधारणा नहीं है। आप निश्चित रूप से एक फ़ाइल @'/folder/subfolder/myfile.txt' और कोई फ़ोल्डर और न ही सबफ़ोल्डर हो सकते हैं।

"अनुकरण" करने के लिए S3 में एक फ़ोल्डर है, तो आप अपने नाम के अंत में के साथ एक '/' एक खाली फ़ाइल बनाने चाहिए (Amazon S3 boto - how to create a folder? देखें)

आपकी समस्या के लिए, आप शायद के साथ विधि get_all_keys का उपयोग करना चाहिए 2 पैरामीटर: prefix और delimiter

https://github.com/boto/boto/blob/develop/boto/s3/bucket.py#L427

for key in bucket.get_all_keys(prefix='first-level/', delimiter='/'): 
    print(key.name) 
+0

मुझे डर है कि मेरे पास बाल्टी ऑब्जेक्ट पर get_all_keys विधि नहीं है। मैं boto3 संस्करण 1.2.3 का उपयोग कर रहा हूँ। –

+0

बस बोटो 1.2 ए की जांच की गई: वहां, बाल्टी में 'उपसर्ग' और 'डिलीमीटर' के साथ एक विधि 'सूची' है। मुझे लगता है कि यह काम करना चाहिए। – Pirheas

+1

जब मैं प्रश्न में पोस्ट करता हूं तो बाल्टी ऑब्जेक्ट पुनर्प्राप्त नहीं होता है। मैं boto3 1.2.6 पर हूं, आपका लिंक किस संस्करण का संदर्भ देता है? –

23

कोड के टुकड़े के नीचे एस 3 बाल्टी से 'फ़ोल्डर' में केवल 'उपफोल्डर' लौटाता है।

import boto3 
bucket = 'my-bucket' 
#Make sure you provide/in the end 
prefix = 'prefix-name-with-slash/' 

client = boto3.client('s3') 
result = client.list_objects(Bucket=bucket, Prefix=prefix, Delimiter='/') 
for o in result.get('CommonPrefixes'): 
    print 'sub folder : ', o.get('Prefix') 

अधिक जानकारी के लिए, आप नवीनतम BOTO3 प्रलेखन अब list_objects_v2 उपयोग करने की सलाह http://boto3.readthedocs.io/en/latest/reference/services/s3.html#S3.Client.list_objects_v2

+0

क्या होगा यदि मैं किसी विशेष उपफोल्डर की सामग्री सूचीबद्ध करना चाहता हूं? –

5

का उल्लेख कर सकते हैं, लेकिन अंत में यहाँ एक है boto3 का उपयोग कर एस 3 बाल्टी में सबफ़ोल्डर की सामग्री सूचीबद्ध करने का सरल तरीका। आशा है कि यह

prefix = "folderone/foldertwo/" 
s3 = boto3.resource('s3') 
bucket = s3.Bucket(name="bucket_name_here") 
FilesNotFound = True 
for obj in bucket.objects.filter(Prefix=prefix): 
    print('{0}:{1}'.format(bucket.name, obj.key)) 
    FilesNotFound = False 
if FilesNotFound: 
    print("ALERT", "No file in {0}/{1}".format(bucket, prefix)) 
1

एडब्ल्यूएस CLI करता है में मदद करता है जब आप aws s3 ls s3://my-bucket/ चलाने (संभवतः लाए जाने और बाल्टी में सभी चाबियाँ के माध्यम से पुनरावृत्ति के बिना), तो मैं समझ boto3 का उपयोग कर एक तरह से होना चाहिए।

https://github.com/aws/aws-cli/blob/0fedc4c1b6a7aee13e2ed10c3ada778c702c22c3/awscli/customizations/s3/subcommands.py#L499

ऐसा लगता है कि वे वास्तव में उपसर्ग और सीमांकक का उपयोग करें - मैं एक समारोह है कि मुझे उस कोड थोड़ा संशोधित करके एक बाल्टी के रूट स्तर पर सभी निर्देशिकाओं मिलेगा लिखने में सक्षम था:

def list_folders_in_bucket(bucket): 
    paginator = boto3.client('s3').get_paginator('list_objects') 
    folders = [] 
    iterator = paginator.paginate(Bucket=bucket, Prefix='', Delimiter='/', PaginationConfig={'PageSize': None}) 
    for response_data in iterator: 
     prefixes = response_data.get('CommonPrefixes', []) 
     for prefix in prefixes: 
      prefix_name = prefix['Prefix'] 
      if prefix_name.endswith('/'): 
       folders.append(prefix_name.rstrip('/')) 
    return folders 
1

मेरे लिए निम्नलिखित काम करता है ... S3 वस्तुओं:

s3://bucket/ 
    form1/ 
     section11/ 
      file111 
      file112 
     section12/ 
      file121 
    form2/ 
     section21/ 
      file211 
      file112 
     section22/ 
      file221 
      file222 
      ... 
     ... 
    ... 

का उपयोग करना:

+०१२३५१६४१०६१
from boto3.session import Session 
s3client = session.client('s3') 
resp = s3client.list_objects(Bucket=bucket, Prefix='', Delimiter="/") 
forms = [x['Prefix'] for x in resp['CommonPrefixes']] 

हम पाते हैं:

form1/ 
form2/ 
... 

के साथ:

resp = s3client.list_objects(Bucket=bucket, Prefix='form1/', Delimiter="/") 
sections = [x['Prefix'] for x in resp['CommonPrefixes']] 

हम पाते हैं:

form1/section11/ 
form1/section12/ 
संबंधित मुद्दे