AWS S3에서 1000개 이상의 객체를 조작하는 방법

8817 단어 파이썬S3boto3AWS
안녕하세요. 퓨처 주식회사 TIG 소속 2020년 신졸의 오니시입니다.
미래 Advent Calendar 2020 3일째를 담당합니다.

현재 업무에서 AWS(특히 S3나 Glue Job 등)를 사용하는 경우가 많기 때문에, 내 자신의 업무로 망설인 경험을 바탕으로 「AWS 초보자가 주저하기 쉬운 포인트와 그 해소법」이라는 테마로 블로그를 써 갑니다.

우선, 오늘 취급하는 테마는 「Boto3을 이용한 1,000건 이상의 S3 오브젝트의 조작」입니다.

갈망 포인트 개요



Boto3은 Python을 통해 AWS를 조작하기 위한 라이브러리입니다.

Boto3을 사용하여 AWS를 조작하는 경우 list_objects_v2 또는 objects.filter와 같은 함수를 사용하여 여러 객체를 검색 할 수있는 기회가 있습니까?
list_object_v2를 가진 객체 검색 예

get_objects.py
import boto3
s3 = boto3.resource("s3")
bucket = s3.Bucket(bucket_name)
prefix = "S3バケットへのパス"
objects = bucket.meta.client.list_objects_v2(Bucket=bucket.name, Prefix=prefix)

그러나 위의 함수에는 "한 번의 요청으로 얻을 수 있는 객체의 수는 1,000건까지"라는 규칙이 있어, 1001번째 이후의 객체는 취득할 수 없습니다.





Boto3 공식 문서의 S3에 대한 설명 부분을 읽으면 S3에서 다음 함수에 비슷한 규칙이있는 것 같습니다.
  • get_bucket_replication()
  • list_bucket_analytics_configurations()
  • list_bucket_inventory_configurations()
  • list_bucket_metrics_configurations()
  • list_multipart_uploads()
  • list_object_versions()
  • list_objects()
  • list_objects_v2()
  • list_parts()
  • put_bucket_analytics_configuration ()
  • put_bucket_inventory_configuration()
  • put_bucket_lifecycle_configuration()
  • put_bucket_metrics_configuration()
  • put_bucket_replication()
  • object_versions.filter()
  • objects.filter()
  • BucketLifecycleConfiguration.put()

  • 해결 방법



    이번에는 예로 list_objects_v2를 사용하는 경우의 해결 방법을 씁니다.

    list_objects_v2의 반환 값의 dict에는 결과가 잘린지 여부를 나타내는 IsTruncated가 포함되어 있습니다.
    그리고, 취득하는 오브젝트수의 상한을 지정하지 않고 list_objects_v2 를 실행해, 취득한 오브젝트의 수가 1000건을 넘고 있었던 경우는, objects["IsTruncated"]에 True가 세트 되어 돌려주어 옵니다.
    또한 list_objects_v2는 인수 StartAfter를 설정하여 지정된 S3 파일의 다음 파일에서 객체를 가져옵니다.

    따라서 objects["IsTruncated"]==True이면 1000 번째 S3 키를 StartAfter로 설정하고 다시 list_objects_v2를 실행하는 프로세스를 ["IsTruncated"]==False가 될 때까지 반복하여 1,000 개 이상의 객체에서도 얻을 수 있습니다. 수 있습니다.

    출처



    get_objects.py
    s3 = boto3.resource("s3")
    bucket = s3.Bucket(source_bucket)
    prefix = "S3バケットへのパス"
    keys = get_all_keys(bucket.name, prefix, [], "")
    
    
    def get_all_keys(bucket_name: str, prefix: str, keys: List[str], marker: str) -> List[str]:
        """
        S3の指定したパスに存在するオブジェクトのキーを全て取得する
    
        Parameters
        ----------
        bucket_name: String
            対象のBucket
        prefix: String
            対象のディレクトリのパス
        keys: List[str]
        marker: String
            関数の中から呼び出す時のための引数。通常はkeys = [], marker = "" で呼び出す
    
        Returns
        -------
        List[str]
            取得したキーのリスト
        """
        s3 = boto3.resource("s3")
        bucket = s3.Bucket(bucket_name)
        objects = bucket.meta.client.list_objects_v2(Bucket=bucket.name, Prefix=prefix, StartAfter=marker)
        if "Contents" in objects:
            keys.extend([content["Key"] for content in objects["Contents"]])
            # 返り値のIsTruncatedがTrueかどうかを確認する
            if objects.get("isTruncated"):
                # marker引数に取得したkeysの末尾の値を設定して再度get_all_keysを実行する
                return get_all_keys(bucket_name=bucket_name, prefix=prefix, keys=keys, marker=keys[-1])
        return keys
    

    마지막으로



    이번에는 「AWS 초보자가 망설이기 쉬운 포인트와 그 해소법」의 제1탄으로서 IsTruncated를 이용한 1,000건 상한의 해결에 대해 정리했습니다.

    대량의 오브젝트를 한 번에 취득하고 싶은 분은 꼭 참고해 보세요.

    좋은 웹페이지 즐겨찾기