다음을 통해 공유


외부 테이블을 외부 Unity 카탈로그 테이블로 변환

중요합니다

이 기능은 공개 미리 보기로 제공되며 현재 참여 고객에게만 제공됩니다. 미리 보기에 참여하려면 이 양식을 작성하여 제출하세요. 이 기능은 HMS 및 Glue 페더레이션을 사용하여 페더레이션된 외부 테이블 변환만 지원합니다.

이 페이지에서는 외장 테이블을 외부 테이블로 변환하는 방법을 SET EXTERNAL 설명합니다.

SET EXTERNAL 개요

SET EXTERNAL 기능을 사용하여 외용 테이블을 Azure Databricks의 Unity 카탈로그 EXTERNAL 테이블로 변환합니다. SET EXTERNAL는 다음과 같은 이점을 제공합니다.

  • 테이블 기록 유지
  • 동일한 이름, 설정, 사용 권한 및 보기를 포함하여 동일한 테이블 구성을 유지합니다.

필수 조건

  • 데이터 형식: 외부 테이블의 데이터 형식은 다음 중 하나여야 합니다.
    • Delta
    • Parquet
    • ORC
    • Avro
    • JSON
    • CSV
    • 텍스트
  • 테이블 형식: HMS 테이블 형식은 외부 HMS 테이블이어야 합니다. 테이블이 관리되는 HMS 테이블이면 명령이 실패합니다.
  • 런타임: Databricks Runtime 17.3 이상
  • 사용 권한: OWNER 또는 MANAGE 테이블에 대한 사용 권한 및 CREATEEXTERNAL LOCATION에 대한 사용 권한

경고

원본 테이블과 Unity 카탈로그의 동시 쓰기는 지원되지 않습니다. 사용자는 외부 카탈로그의 원본 테이블에 대한 읽기 및 쓰기를 사용하지 않도록 설정하여 변환을 수행하기 전에 워크로드가 새 카탈로그로 마이그레이션되었는지 확인할 책임이 있습니다.

문법

Unity 카탈로그 외세 테이블을 Unity 카탈로그 외부로 변환하려면 다음 명령을 실행합니다.

ALTER TABLE source_table SET EXTERNAL [DRY RUN]

매개 변수

  • source_table

    Unity 카탈로그의 기존 외부 테이블입니다. 외장 테이블에는 외부 카탈로그에서 관리하는 데이터 및 메타데이터가 포함됩니다. 변환하기 전에 원본 테이블을 외부 카탈로그에 놓으면 Unity 카탈로그에서도 외국 테이블이 삭제됩니다. 테이블이 외부로 변환되면 외부 카탈로그에서 원본 테이블을 삭제해도 Unity 카탈로그 외부 테이블에는 영향을 주지 않습니다.

  • DRY RUN

    지정된 경우 대상 테이블을 업그레이드하지 않고 원본 테이블을 업그레이드할 수 있는지 여부를 확인합니다. 이 명령은 테이블을 업그레이드할 수 있는 경우 DRY_RUN_SUCCESS를 반환합니다.

롤백

테이블 마이그레이션을 되돌리려면 테이블을 삭제한 다음, 다음 카탈로그를 동기화할 때 외부 테이블로 다시 페더레이션됩니다.

DROP TABLE catalog.schema.my_external_table;

변환 확인

카탈로그 탐색기를 확인하여 외세 테이블이 외부 테이블로 변환되었는지 확인할 수 있습니다. 변환하기 전에 테이블은 Foreign로 표시되고 변환 후에 는 외부로 표시됩니다.

비고

실행 중인 DESCRIBE EXTENDED 테이블 형식은 변환 전후로 EXTERNAL 표시됩니다. 이는 페더레이션이 카탈로그에서 이 명령을 hive_metastore 실행하는 동작과 모방하기 때문에 작동하기 때문입니다. 변환을 정확하게 확인하려면 카탈로그 탐색기를 사용합니다.

자주 묻는 질문(FAQ)

테이블을 만들고 외국 카탈로그에서 테이블을 변환할 수 있나요?

예, 외부 또는 관리형 테이블을 외국 카탈로그에 만들 수 있습니다. 동작은 스키마 구성에 따라 달라집니다.

  • Glue 또는 eHMS 스키마의 경우 또는 Unity 카탈로그에서 관리되는 위치가 설정된 스키마의 경우: 실행하는 CREATE TABLE foreign_catalog.schema.table경우 Unity 카탈로그 관리 테이블 또는 외부 테이블이 만들어집니다. 테이블이 외부 카탈로그에 푸시되거나 동기화되지 않습니다.
  • 내부 Hive 메타스토어 연결의 스키마의 경우: 외부 스키마에서 테이블을 만들려고 하면 여전히 외부 테이블을 생성하고 hive_metastore에 테이블을 만듭니다.
  • 레거시 작업 영역 Hive 메타스토어의 경우: 읽기 및 쓰기 페더레이션이므로 외세의 카탈로그에 테이블을 만들면 내부 Hive 메타스토어에도 테이블이 만들어집니다.

외장 테이블이 SerDe 형식이면 어떻게 될까요?

AWS Glue의 Parquet SerDe 테이블의 경우 외부 테이블로 변환하기 전에 테이블 메타데이터를 수정해야 합니다. 다음 Python 스크립트는 AWS boto3 라이브러리를 사용하여 필요한 속성을 업데이트합니다.

import boto3
import json

# Initialize boto3 Glue client with your AWS region
glue_client = boto3.client('glue', region_name='<your-aws-region>')  # Example: 'us-west-2'

# Configure your table details
DATABASE_NAME = '<your-database-name>'  # Example: 'my_database'
TABLE_NAME = '<your-table-name>'  # Example: 'my_parquet_table'
SPARK_PROVIDER = 'PARQUET'
SPARK_PARTITION_PROVIDER = 'filesystem'

# Step 1: Get the current table definition
print(f"Retrieving current table definition for {DATABASE_NAME}.{TABLE_NAME}...")
response = glue_client.get_table(DatabaseName=DATABASE_NAME, Name=TABLE_NAME)

# Extract the table's current definition
table_definition = response['Table']

# Step 2: Verify if the table is a Parquet SerDe
serde_library = table_definition['StorageDescriptor']['SerdeInfo'].get('SerializationLibrary', '')
is_parquet_serde = serde_library == "org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe"

if not is_parquet_serde:
    print(f"The table {TABLE_NAME} does not use a Parquet SerDe. Found: {serde_library}")
else:
    print(f"Table {TABLE_NAME} is using a Parquet SerDe.")

    # Step 3: Extract the S3 path dynamically from the Location field
    s3_path = table_definition['StorageDescriptor']['Location']
    print(f"S3 Path found: {s3_path}")

    # Step 4: Modify the SerDe and table properties
    # Modify SerDe parameters
    if 'SerdeInfo' in table_definition['StorageDescriptor']:
        if 'Parameters' not in table_definition['StorageDescriptor']['SerdeInfo']:
            table_definition['StorageDescriptor']['SerdeInfo']['Parameters'] = {}
        table_definition['StorageDescriptor']['SerdeInfo']['Parameters']['path'] = s3_path

    # Modify table properties
    if 'Parameters' not in table_definition:
        table_definition['Parameters'] = {}

    # Set both spark.sql.sources.provider and spark.sql.partitionProvider
    table_definition['Parameters']['spark.sql.sources.provider'] = SPARK_PROVIDER
    table_definition['Parameters']['spark.sql.partitionProvider'] = SPARK_PARTITION_PROVIDER

    # Remove metadata fields that are not accepted by update_table API
    table_definition.pop('CreateTime', None)
    table_definition.pop('UpdateTime', None)
    table_definition.pop('LastAccessTime', None)
    table_definition.pop('Retention', None)
    table_definition.pop("DatabaseName", None)
    table_definition.pop('CreatedBy', None)
    table_definition.pop('IsRegisteredWithLakeFormation', None)
    table_definition.pop('CatalogId', None)
    table_definition.pop('VersionId', None)

    # Step 5: Update the table with the modified properties
    print(f"Updating the table {TABLE_NAME} in Glue...")
    response = glue_client.update_table(
        DatabaseName=DATABASE_NAME,  # Correct use of DatabaseName
        TableInput=table_definition,
    )

    print(f"Table {TABLE_NAME} updated successfully!")

외부 테이블이 DBFS로 뒷받침되면 어떻게 되나요?

DBFS 지원 테이블을 변환할 때 클라우드 경로에 대한 DBFS 경로의 현재 매핑을 외부 테이블의 클라우드 경로 위치로 저장합니다.

스키마 또는 카탈로그 수준에서 변환할 수 있나요?

스키마의 테이블을 반복하여 개별적으로 변환하거나 discoverx labs 프로젝트를 활용하여 전체 스키마 또는 카탈로그를 한 번에 변환할 수 있습니다.

df = (dx.from_tables("prod.*.*")
.with_sql("ALTER TABLE {full_table_name} SET EXTERNAL;")
.apply())  # dry run with .explain()