Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Boto3를 사용해 AWS Glue의 모든 작업(Job) 정의를 한 번에 조회하는 방법

문제 상황

Python에서 boto3 라이브러리를 활용하여 사용자의 AWS Glue Data Catalog에 등록된 모든 Glue 작업(Job)의 정의를 한 번에 조회하는 방법을 알아보겠습니다.

예를 들어, AWS Glue Data Catalog에 존재하는 전체 Glue 작업의 정의(이름, 역할, 생성일, 실행 속성, 스크립트 위치 등)를 가져오고자 하는 경우가 이에 해당합니다.

해결 접근 방식 및 알고리즘

1단계

예외 처리를 위해 boto3botocore.exceptions를 임포트합니다.

2단계

이 함수에는 별도의 파라미터가 필요하지 않습니다. 호출 시 사용자 계정에 등록된 모든 작업의 정의를 자동으로 가져옵니다.

3단계

boto3 라이브러리를 사용하여 AWS 세션(Session)을 생성합니다. 기본 프로필(default profile)에 region_name이 설정되어 있는지 확인하세요. 만약 설정되어 있지 않다면, 세션 생성 시 region_name을 명시적으로 전달해야 합니다.

4단계

Glue 서비스를 위한 AWS 클라이언트(Client)를 생성합니다.

5단계

get_jobs() 함수를 호출하여 사용자 계정에 나열된 모든 작업의 정의를 조회합니다. 여기서 주의할 점은 list_jobsget_jobs의 차이입니다. list_jobs는 AWS Glue Data Catalog에 존재하는 Glue 작업의 이름 목록만 반환하는 반면, get_jobs는 각 작업의 상세 정의 전체를 가져옵니다.

6단계

함수는 각 작업의 정의를 딕셔너리 형태로 반환합니다.

7단계

작업 조회 중 문제가 발생했을 경우를 대비해 일반 예외(generic exception)를 처리하는 로직을 추가합니다.

예제 코드

아래 코드를 사용하면 사용자 계정에 등록된 각 작업의 정의를 조회할 수 있습니다.

import boto3
from botocore.exceptions import ClientError

def get_definition_of_glue_jobs():
    session = boto3.session.Session()
    glue_client = session.client('glue')
    try:
        response = glue_client.get_jobs()
        return response
    except ClientError as e:
        raise Exception("boto3 client error in get_definition_of_glue_jobs: " + e.__str__())
    except Exception as e:
        raise Exception("Unexpected error in get_definition_of_glue_jobs: " + e.__str__())

print(get_definition_of_glue_jobs())

실행 결과

위 코드를 실행하면 다음과 같이 각 작업의 이름(Name), IAM 역할(Role), 생성일(CreatedOn), 최종 수정일(LastModifiedOn), 실행 속성(ExecutionProperty), 명령(Command), 스크립트 위치(ScriptLocation), 타임아웃(Timeout), Glue 버전(GlueVersion) 등의 상세 정보가 포함된 응답을 확인할 수 있습니다.

{'Jobs': [
{'Name': '01_PythonShellTest1', 'Role': 'arn:aws:iam::********:role/devedl-glue-role', 'CreatedOn': datetime.datetime(2021, 1, 6, 19, 59, 19, 387000, tzinfo=tzlocal()), 'LastModifiedOn': datetime.datetime(2021, 2, 9, 21, 47, 31, 614000, tzinfo=tzlocal()), 'ExecutionProperty': {'MaxConcurrentRuns': 1}, 'Command': {'Name': 'pythonshell', 'ScriptLocation': 's3://ivz-dev-ds-staging-/01_pythonShellTest/test1/01_PythonShellTest1.py', 'PythonVersion': '3'}, 'DefaultArguments': {'--job-bookmark-option': 'job-bookmark-disable', '--job-language': 'python'}, 'MaxRetries': 0, 'AllocatedCapacity': 0, 'Timeout': 2880, 'MaxCapacity': 0.0625, 'GlueVersion': '1.0'},
{'Name': '01_pythonSHELL_14012021', 'Role': 'arn:aws:iam::*********:role/dev-edl-glue-role', 'CreatedOn': datetime.datetime(2021, 1, 14, 20, 22, 40, 965000, tzinfo=tzlocal()), 'LastModifiedOn': datetime.datetime(2021, 1, 14, 20, 22, 40, 965000, tzinfo=tzlocal()), 'ExecutionProperty': {'MaxConcurrentRuns': 1}, 'Command': {'Name': 'pythonshell', 'ScriptLocation': 's3://ivz-dev-dsstaging-work/ /test_14012021/01_pythonSHELL_14012021_123.py', 'PythonVersion': '3'}, 'DefaultArguments': {'--job-bookmark-option': 'jobbookmark-disable'}, 'MaxRetries': 0, 'AllocatedCapacity': 0, 'Timeout': 2880, 'MaxCapacity': 0.0625, 'GlueVersion': '1.0'},
{'Name': 'GlueConnectionTest', 'Role': 'arn:aws:iam::*********:role/devedl-qa-automation-glue-role', 'CreatedOn': datetime.datetime(2020, 3, 6, 16, 27, 3, 862000, tzinfo=tzlocal()), 'LastModifiedOn': datetime.datetime(2020, 3, 6, 16, 49, 19, 942000, tzinfo=tzlocal()), 'ExecutionProperty': {'MaxConcurrentRuns': 1}, 'Command': {'Name': 'pythonshell', 'ScriptLocation': 's3://glue-job-connection-testbucket/test.py', 'PythonVersion': '3'}, 'DefaultArguments': {'--jobbookmark-option': 'job-bookmark-disable', '--job-language': 'python'}, 'Connections': {'Connections': ['dev-edl-redshift-glue-connection', 'devedl-rds-glue-connection']}, 'MaxRetries': 0, 'AllocatedCapacity': 0, 'Timeout': 2880, 'MaxCapacity': 0.0625, 'GlueVersion': '1.0'}], 'NextToken': 'eyJleHBpcmF0aW9uIjp7InNlY29uZHMiOjE2MTQ2NjI2MTAsIm5hbm9zIjo2MjEwMDAwMDB9LCJsYXN0RXZhbHVhdGVkS2V5Ijp7ImpvYk5hbWUiOnsicyI6InRpY2stZGF0YS10ZXN0In0sImFjY291bnRJZCI6eyJzIjoiNzgyMjU4NDg1ODQxIn0sImpvYklkIjp7InMiOiJqXzhmZDc2MzhkYTcyMGQ5Yzk1YTg4MTlkOTgxNTE5MDdjM2JmYWI3ZGYxNGUwNGExZGM0ZTIzZjViYjczM2M2ZTYifX19', 'ResponseMetadata': {'RequestId': '287ad828-**************************af', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Mon, 01 Mar 2021 05:23:30 GMT', 'content-type': 'application/x-amz-json-1.1', 'content-length': '8258', 'connection': 'keep-alive', 'x-amzn-requestid': '287ad828-*****************af'}, 'RetryAttempts': 0}}

참고 사항

응답 결과에 포함된 NextToken 값은 페이징(pagination) 처리에 사용됩니다. 등록된 작업 수가 많아 한 번의 요청으로 전체 결과를 받지 못한 경우, 다음 요청 시 이 토큰을 NextToken 파라미터로 전달하면 나머지 작업의 정의를 이어서 조회할 수 있습니다.