Boto3에서 S3 버켓의 오브젝트가 1000개 이상일 때 리스트 조회하기

Python의 SDK인 Boto3를 사용하여 S3 버켓의 오브젝트가 1000개 이상일 때 오브젝트의 리스트를 조회하는 방법
2023.02.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

안녕하세요 DA사업본부 송영진입니다.

오늘은 Python의 SDK인 Boto3를 사용하여 S3 버켓의 오브젝트가 1000개 이상일 때 오브젝트의 리스트를 조회하는 방법에 대해 알아보겠습니다.

Boto3에서 S3 오브젝트 확인하는 방법

Boto3의 S3 메소드 중에서 가장 대표적으로 오브젝트를 가져오는 메소드는 다음과 같습니다.

list_objects()는 AWS에서 지원을 하지만 list_objects_v2()를 사용하는 것을 추천하고 있습니다. 사실상 선택지는 하나가 되겠습니다.

list_objects_v2()를 사용해서 오브젝트 리스트 조회

위와 같이 0001.txt 부터 1005.txt까지 1000개를 살짝 넘는 오브젝트를 S3 버켓에 업로드 했습니다. 이제 list_objects_v2()를 사용하여 리스트를 조회해보겠습니다.

import boto3

client = boto3.client('s3')
response = client.list_objects_v2(Bucket='cm-song', Prefix='list_objects')

list = [keys['Key'] for keys in response['Contents']]

print("length of list: ", len(list))
print("tail of list: ", list[-5:])
length of list: 1000
tail of list: ['list_objects/0996.txt', 'list_objects/0997.txt', 'list_objects/0998.txt', 'list_objects/0999.txt', 'list_objects/1000.txt']

하지만 이 list_objects_v2()는 한 번에 최대 1,000개의 오브젝트밖에 반환되지 않습니다. 반환값에서 isTruncatedNextContinuationToken를 사용하여 다음 1000개의 오브젝트를 찾을 수 있습니다. 다음과 같이 사용해보겠습니다.

while response['IsTruncated']
    response = client.list_objects_v2(Bucket='cm-song', Prefix='list_objects', ContinuationToken=response['NextContinuationToken'])
    list += [keys['Key'] for keys in res['Contents']]

print("length of list: ", len(list))
print("tail of list: ", list[-5:])
length of list: 1005
tail of list: ['list_objects/1001.txt', 'list_objects/1002.txt', 'list_objects/1003.txt', 'list_objects/1004.txt', 'list_objects/1005.txt']

get_paginator()를 사용해서 오브젝트 리스트 조회

다른 방법으로는 페이지네이터를 사용하는 방법입니다. 주로 이 방법을 선호하시는 분들이 많더라구요

import boto3

client = boto3.client('s3')
paginator = client.get_paginator('list_objects_v2')
page_iterator = paginator.paginate(Bucket='cm-song', Prefix='list_objects')

list = []
for page in page_iterator:
    list += [keys['Key'] for keys in page['Contents']]

print("length of list: ", len(list))
print("tail of list: ", list[-5:])
length of list: 1005
tail of list: ['list_objects/1001.txt', 'list_objects/1002.txt', 'list_objects/1003.txt', 'list_objects/1004.txt', 'list_objects/1005.txt']

위와 같은 코드로 list_objects_v2의 모든 페이지를 page_iterator에서 사용 할 수 있게 됩니다.

끝으로

일정한 주기로 S3의 오브젝트 리스트에서 최신 파일을 사용하는 프로그램이 있었는데 어느정도 시간 이후로 갱신이 없길래 왜 안되지... 하면서 로그를 보니 S3 오브젝트 리스트가 1000개 이후로 보이지가 않더라구요. 그제서야 SDK에서 반환하는 개수가 1000개 제한이 있다는 것을 알았습니다. 지금은 페이지네이터를 사용하는 방법으로 해결을 한 상태인데요, Boto3를 사용해서 S3를 다루시는 분들은 한 번쯤 겪게 되는 일이 아닐까 싶습니다. 미래에 또 까먹을 저를 위해서 처음 겪으시는 분들께 도움이 되길 바랍니다!