メインコンテンツまでスキップ

フォーリンテーブルを外部Unity Catalogテーブルに変換する

備考

プレビュー

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

このページでは、 SET EXTERNALを使用してフォーリンテーブルを外部テーブルに変換する方法について説明します。

SET EXTERNAL概要

SET EXTERNAL機能を使用して、フォーリンテーブルをDatabricksのUnity Catalog EXTERNALテーブルに変換します。 SET EXTERNALは次の利点があります:

  • テーブル履歴の保持
  • 同じ名前、設定、権限、ビューなど、同じテーブル構成を維持します。

前提条件

  • データ形式 : フォーリンテーブルのデータ形式は次のいずれかである必要があります。

    • Delta
    • PARQUET
    • ORC
    • AVRO
    • JSON
    • CSV
    • TEXT
  • テーブル タイプ : HMS テーブル タイプは外部 HMS テーブルである必要があります。テーブルが管理対象 HMS テーブルの場合、コマンドは失敗します。

  • Runtime : Databricks Runtime 17.3 以上

  • 権限 : テーブルに対するOWNERまたはMANAGE権限とCREATE EXTERNAL LOCATION

警告

ソース テーブルへの書き込みとUnity Catalogからの書き込みはサポートされていません。 変換を実行する前に、外部カタログ内のソース テーブルへの読み取りと書き込みを無効にし、ワークロードが新しいカタログに移行されていることを確認する必要があります。

構文

Unity CatalogフォーリンテーブルをUnity Catalog外部に変換するには、次のコマンドを実行します。

SQL
ALTER TABLE source_table SET EXTERNAL [DRY RUN]

パラメーター

  • ソーステーブル

    Unity Catalog内の既存のフォーリンテーブル。 フォーリンテーブルには、外部カタログによって管理されるデータとメタデータが含まれます。 変換前に、ソース テーブルを外部カタログにドロップすると、フォーリン テーブルもUnity Catalogにドロップされます。 テーブルを外部に変換した後、外部カタログ内のソース テーブルを削除しても、Unity Catalog 外部テーブルには影響しません。

  • DRY RUN

    指定すると、ターゲット テーブルをアップグレードせずにソース テーブルをアップグレードできるかどうかを確認します。テーブルをアップグレードできる場合、コマンドはDRY_RUN_SUCCESSを返します。

ロールバック

テーブルの移行をロールバックするには、テーブルを削除し、次のカタログ同期で外部として再フェデレーションします。

SQL
DROP TABLE catalog.schema.my_external_table;

変換を確認する

カタログ エクスプローラーで確認すると、フォーリンテーブルが外部テーブルに変換されたことを確認できます。 変換前はテーブルに Foreign と表示され、変換後は External と表示されます。

注記

DESCRIBE EXTENDEDを実行すると、変換前と変換後の両方でテーブル タイプがEXTERNALとして表示されます。これは、フェデレーションの動作によるもので、 hive_metastoreカタログでこのコマンドを実行する動作を模倣しています。変換を正確に検証するには、カタログ エクスプローラーを使用します。

よくある質問

フォーリンカタログでテーブルを作成したり、テーブルを変換したりすることはできますか?

はい、フォーリンカタログで外部テーブルまたはマネージドテーブルを作成できます。 動作はスキーマ構成によって異なります。

  • Glue または eHMS スキーマの場合 、あるいは Unity Catalog で管理場所が設定されているスキーマの場合 : CREATE TABLE foreign_catalog.schema.tableを実行すると、Unity Catalog で管理されるテーブルまたは外部テーブルが作成されます。テーブルは外部カタログにプッシュまたは同期されません。
  • 内部Hive metastore接続からのスキーマの場合 : 外部スキーマにテーブルを作成しようとすると、引き続きフォーリン テーブルが作成され、 hive_metastoreにもテーブルが作成されます。
  • 従来のワークスペースHive metastoreの場合 : 読み取りおよび書き込みフェデレーションであるため、フォーリンカタログにテーブルを作成すると、内部のHive metastoreにもテーブルが作成されます。

私のフォーリンテーブルが SerDe 形式の場合はどうなりますか?

AWS Glue の Parquet SerDe テーブルの場合、外部テーブルに変換する前にテーブルメタデータを変更する必要があります。次の Python スクリプトは、AWS boto3 ライブラリを使用して必要なプロパティを更新します。

Python
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 プロジェクトを利用してスキーマまたはカタログ全体を一度に変換することもできます。

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