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

Boto3로 AWS Glue Data Catalog에서 데이터베이스 테이블 정의 조회하는 방법

이 글에서는 Boto3를 사용하여 AWS Glue Data Catalog의 특정 데이터베이스에 있는 전체 테이블 또는 정규 표현식과 일치하는 일부 테이블의 정의를 조회하는 방법을 살펴보겠습니다.

예제 시나리오

데이터베이스 'QA-test'에 포함된 모든 테이블 중에서 'security''employee' 테이블의 정의를 가져와 보겠습니다.

문제 해결 접근 방식

  • 1단계: 예외 처리를 위해 boto3botocore의 예외 클래스를 임포트합니다.

  • 2단계: database_name은 필수 파라미터이며, regular_expression_for_table_name은 선택적 파라미터입니다. 모든 테이블의 정보를 가져오려면 정규 표현식을 지정할 필요가 없습니다. 반면 특정 테이블만 조회하려면 정규 표현식을 반드시 입력해야 합니다. 정규 표현식을 잘못 작성하면 결과가 달라질 수 있으므로 주의해서 작성해야 합니다.

  • 3단계: boto3 라이브러리를 사용하여 AWS 세션을 생성합니다. 기본 프로필에 region_name이 설정되어 있는지 확인하고, 설정되어 있지 않다면 세션 생성 시 region_name을 명시적으로 전달해야 합니다.

  • 4단계: glue 서비스용 AWS 클라이언트를 생성합니다.

  • 5단계: get_tables 함수를 호출하면서 database_name은 DatabaseName 파라미터로, regular_expression_for_table_name은 Expression 파라미터로 전달합니다.

  • 6단계: 지정된 데이터베이스 내 전체 테이블 또는 조건에 일치하는 테이블의 정의가 반환됩니다.

  • 7단계: 조회 과정에서 오류가 발생할 경우 일반 예외를 처리합니다.

예제 코드

다음 코드는 지정된 데이터베이스에서 모든 테이블 정의를 조회합니다.

import boto3
from botocore.exceptions import ClientError

def retrieves_tables_detail(database_name, regular_expression_for_table_name=None)
   session = boto3.session.Session()
   glue_client = session.client('glue')
   try:
      response = glue_client.get_tables(DatabaseName = database_name, Expression=regular_expression_for_table_name)                      
      return response
   except ClientError as e:
      raise Exception(
         "boto3 client error in retrieves_tables_detail: " + e.__str__())
   except Exception as e:
      raise Exception(
         "Unexpected error in retrieves_tables_detail: " + e.__str__())
print(retrieves_tables_detail('QA-test'))

출력 결과

위 코드를 실행하면 다음과 같이 테이블 이름, 스키마(컬럼 정보), 저장 위치, 파일 형식, 크롤러 메타데이터 등 각 테이블의 상세 정보가 담긴 응답을 확인할 수 있습니다.

{'TableList': [
{'Name': 'security', 'DatabaseName': 'QA-test', 'Owner': 'owner', 'CreateTime': datetime.datetime(2020, 9, 10, 22, 27, 24, tzinfo=tzlocal()), 'UpdateTime': datetime.datetime(2021, 3, 1, 11, 43, 49, tzinfo=tzlocal()), 'LastAccessTime': datetime.datetime(2020, 9, 10, 22, 27, 24, tzinfo=tzlocal()), 'Retention': 0, 'StorageDescriptor': {'Columns': [{'Name': 'assettypecode', 'Type': 'string'}, {'Name': 'industrysector', 'Type': 'varchar'}, {'Name': 'securitycode', 'Type': 'char'}, {'Name': 'contractsize', 'Type': 'string'}, {'Name': 'conversionperiodenddate', 'Type': 'string'}, {'Name': 'conversionperiodstartdate', 'Type': 'string'}, {'Name': 'expirationdate', 'Type': 'string'}, {'Name': 'issuercountrycode', 'Type': 'string'}, {'Name': 'issuercountrydesc', 'Type': 'string'}, {'Name': 'originalissuedate', 'Type': 'string'}, {'Name': 'securitynamelong', 'Type': 'string'}, {'Name': 'issueshortname', 'Type': 'string'}, {'Name': 'gicssector', 'Type': 'string'}, {'Name': 'maturitydate', 'Type': 'string'}, {'Name': 'optioncode', 'Type': 'string'}, {'Name': 'optiontypename', 'Type': 'string'}, {'Name': 'paramount', 'Type': 'string'}, {'Name': 'priceindex', 'Type': 'string'}, {'Name': 'countrycoderisk', 'Type': 'string'}, {'Name': 'countrydescrisk', 'Type': 'string'}, {'Name': 'countrycode', 'Type': 'string'}], 'Location': 's3://test/security/', 'InputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat', 'OutputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat', 'Compressed': False, 'NumberOfBuckets': -1, 'SerdeInfo': {'SerializationLibrary': 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe', 'Parameters': {'serialization.format': '1'}}, 'BucketColumns': [], 'SortColumns': [], 'Parameters': {'CrawlerSchemaDeserializerVersion': '1.0', 'CrawlerSchemaSerializerVersion': '1.0', 'UPDATED_BY_CRAWLER': 'security', 'averageRecordSize': '181', 'classification': 'parquet', 'compressionType': 'none', 'objectCount': '5', 'recordCount': '154800', 'sizeKey': '20337230', 'typeOfData': 'file'}, 'StoredAsSubDirectories': False}, 'PartitionKeys': [], 'TableType': 'EXTERNAL_TABLE', 'Parameters': {'CrawlerSchemaDeserializerVersion': '1.0', 'CrawlerSchemaSerializerVersion': '1.0', 'UPDATED_BY_CRAWLER': 'security', 'averageRecordSize': '181', 'classification': 'parquet', 'compressionType': 'none', 'objectCount': '5', 'recordCount': '154800', 'sizeKey': '20337230', 'typeOfData': 'file'}, 'CreatedBy': 'arn:aws:sts::*********:assumed-role/glue-role/AWS-Crawler'}, 'VersionId': '2'},
{'Name': 'employee', 'DatabaseName': 'QA-test', 'Owner': 'owner', 'CreateTime': datetime.datetime(2020, 9, 10, 22, 27, 24, tzinfo=tzlocal()), 'UpdateTime': datetime.datetime(2021, 3, 1, 11, 43, 49, tzinfo=tzlocal()), 'LastAccessTime': datetime.datetime(2020, 9, 10, 22, 27, 24, tzinfo=tzlocal()), 'Retention': 0, 'StorageDescriptor': {'Columns': [{'Name': 'assettypecode', 'Type': 'string'}, {'Name': 'industrysector', 'Type': 'varchar'}, {'Name': 'code', 'Type': 'char'}, {'Name': 'size', 'Type': 'string'}, {'Name': 'countrycode', 'Type': 'string'}, {'Name': 'countrydesc', 'Type': 'string'}], 'Location': 's3://test/security/', 'InputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat', 'OutputFormat': 'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat', 'Compressed': False, 'NumberOfBuckets': -1, 'SerdeInfo': {'SerializationLibrary': 'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe', 'Parameters': {'serialization.format': '1'}}, 'BucketColumns': [], 'SortColumns': [], 'Parameters': {'CrawlerSchemaDeserializerVersion': '1.0', 'CrawlerSchemaSerializerVersion': '1.0', 'UPDATED_BY_CRAWLER': 'security', 'averageRecordSize': '181', 'classification': 'parquet', 'compressionType': 'none', 'objectCount': '5', 'recordCount': '154800', 'sizeKey': '20337230', 'typeOfData': 'file'}, 'StoredAsSubDirectories': False}, 'PartitionKeys': [], 'TableType': 'EXTERNAL_TABLE', 'Parameters': {'CrawlerSchemaDeserializerVersion': '1.0', 'CrawlerSchemaSerializerVersion': '1.0', 'UPDATED_BY_CRAWLER': 'employee', 'averageRecordSize': '181', 'classification': 'parquet', 'compressionType': 'none', 'objectCount': '5', 'recordCount': '154800', 'sizeKey': '20337230', 'typeOfData': 'file'}, 'CreatedBy': 'arn:aws:sts::*********:assumed-role/glue-role/AWS-Crawler'}, 'VersionId': '2'}, 'ResponseMetadata': {'RequestId': '431db171-*******************0', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Mon, 01 Mar 2021 06:15:30 GMT', 'content-type': 'application/x-amz-json-1.1', 'content-length': '3916', 'connection': 'keep-alive', 'x-amzn-requestid': '431db171-*****************0'}, 'RetryAttempts': 0}}

마무리

이처럼 boto3의 get_tables API를 활용하면 단 몇 줄의 코드로 AWS Glue Data Catalog에 등록된 테이블 메타데이터를 손쉽게 조회할 수 있습니다. 정규 표현식을 함께 사용하면 원하는 테이블만 선별적으로 가져올 수 있어 대규모 데이터 카탈로그를 관리할 때 특히 유용합니다.