문제 개요
이 글에서는 Python의 boto3 라이브러리를 사용하여, 본인 계정에서 생성된 AWS Glue Data Catalog의 S3 버킷에 존재하는 멀티파트 업로드(multi-part upload) 객체를 페이지네이션(페이지 매김)하는 방법을 단계별로 살펴봅니다.
해결 접근 방식 및 알고리즘
1단계: 예외 처리를 위해 boto3와 botocore의 예외 모듈을 임포트합니다.
2단계: 함수의 매개변수를 정의합니다. bucket_name은 필수 매개변수이며, prefix_name, max_items, page_size, starting_token은 선택적 매개변수입니다.
prefix_name: 사용자가 페이지네이션하려는 특정 하위 폴더 경로입니다.
max_items: 반환할 레코드의 총 개수입니다. 사용 가능한 레코드 수가 max_items보다 많으면 응답에 NextToken이 포함되어 이후 페이지네이션을 이어갈 수 있습니다.
page_size: 한 페이지당 포함될 레코드 수입니다.
starting_token: 페이지네이션을 시작할 위치를 지정하며, 이전 응답의 Marker 값을 활용합니다.
3단계: boto3 라이브러리로 AWS 세션을 생성합니다. 기본 프로필에 region_name이 설정되어 있지 않다면, 세션 생성 시 반드시 명시적으로 전달해야 합니다.
4단계: S3 서비스를 위한 AWS 클라이언트를 생성합니다.
5단계: list_multipart_uploads 연산을 기반으로, S3 버킷의 멀티파트 업로드 정보를 담는 페이지네이터(paginator) 객체를 생성합니다.
6단계: paginate 함수를 호출하면서 max_items, page_size, starting_token은 PaginationConfig 매개변수로, bucket_name은 Bucket 매개변수로, prefix_name은 Prefix 매개변수로 각각 전달합니다.
7단계: max_items와 page_size 설정값에 따라 해당 개수만큼의 레코드가 반환됩니다.
8단계: 페이지네이션 도중 오류가 발생하면 일반 예외(generic exception)를 처리합니다.
예제 코드
아래 코드를 사용하면 사용자 계정에 생성된 S3 버킷의 멀티파트 업로드 객체를 페이지네이션할 수 있습니다.
import boto3
from botocore.exceptions import ClientError
def paginate_through_multipart_upload_s3_bucket(bucket_name, prefix_name=None,
max_items=None, page_size=None,
starting_token=None):
session = boto3.session.Session()
s3_client = session.client('s3')
try:
paginator = s3_client.get_paginator('list_multipart_uploads')
response = paginator.paginate(
Bucket=bucket_name,
Prefix=prefix_name,
PaginationConfig={
'MaxItems': max_items,
'PageSize': page_size,
'StartingToken': starting_token
}
)
return response
except ClientError as e:
raise Exception("boto3 client error in paginate_through_multipart_upload_s3_bucket: " + e.__str__())
except Exception as e:
raise Exception("Unexpected error in paginate_through_multipart_upload_s3_bucket: " + e.__str__())
a = paginate_through_multipart_upload_s3_bucket('s3-test-bucket', 'testfolder', 2, 5)
print(*a)출력 결과
위 코드를 실행하면 다음과 같은 형태의 결과가 출력됩니다.
{'ResponseMetadata': {'RequestId': 'YA9CGTAAX', 'HostId': '8dqJW******************', 'HTTPStatusCode': 200, 'HTTPHeaders': {'x-amz-id-2': '8dqJW*********************', 'x-amz-request-id': 'YA9CGTAAX', 'date': 'Sat, 03 Apr 2021 08:16:05 GMT', 'content-type': 'application/xml', 'transfer-encoding': 'chunked', 'server': 'AmazonS3'}, 'RetryAttempts': 0}, 'Bucket': 's3-test-bucket', 'KeyMarker': '', 'UploadIdMarker': '', 'NextKeyMarker': '', 'Prefix': 'testfolder', 'NextUploadIdMarker': '', 'MaxUploads': 5, 'IsTruncated': False, 'Uploads': [
{'UploadId': 'YADF**************LK25',
'Key': 'testfolder/testfilemultiupload.csv',
'Initiated': datetime(2021, 1, 2),
'StorageClass': 'STANDARD',
'Owner': {
'DisplayName': 'AmazonServicesJob',
'Id': '********************'
}
}], 'CommonPrefixes': None}출력 결과에는 요청 메타데이터(ResponseMetadata), 대상 버킷 이름, 마커 정보와 함께 Uploads 배열 내에 각 멀티파트 업로드의 UploadId, Key(객체 키), 업로드 시작 시간(Initiated), 스토리지 클래스(StorageClass), 소유자(Owner) 정보가 포함됩니다. 또한 IsTruncated 값이 False라면 더 이상 조회할 남은 페이지가 없다는 의미입니다.