次の方法で共有


外部テーブルを外部 Unity カタログ テーブルに変換する

Important

この機能はパブリック プレビュー段階であり、現時点では参加しているお客様のみが利用できます。 プレビューに参加するには、 このフォームに入力して申請します。 この機能は、 HMS と Glue Federation を使用してフェデレーションされた外部テーブルの変換のみをサポートします。

このページでは、 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のアクセス許可、およびCREATEに対するEXTERNAL LOCATIONのアクセス許可。

Warnung

ソース テーブルと 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 として表示され、変換後は External と表示されます。

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()