Sdílet prostřednictvím


Převod cizí tabulky na externí tabulku katalogu Unity

Důležité

Tato funkce je ve verzi Public Preview a je dostupná jenom pro zúčastněné zákazníky. Pokud se chcete zúčastnit náhledu, přihlaste se vyplněním tohoto formuláře. Tato funkce podporuje jenom převod cizích tabulek federovaných pomocí HMS a Glue Federation.

Tato stránka popisuje, jak lze převést SET EXTERNAL cizí tabulku na externí tabulku.

SET EXTERNAL přehled

SET EXTERNAL Pomocí této funkce můžete převést cizí tabulku na tabulku Katalogu EXTERNAL Unity v Azure Databricks. SET EXTERNAL nabízí následující výhody:

  • Zachování historie tabulek
  • Zachování stejné konfigurace tabulek, včetně stejného názvu, nastavení, oprávnění a zobrazení

Požadavky

  • Formát dat: Formát dat cizí tabulky musí být jeden z následujících:
    • Delta
    • Parquet
    • ORC
    • Avro
    • JSON
    • formát CSV
    • TEXT
  • Typ tabulky: Typ tabulky HMS musí být externí tabulka HMS. Příkaz selže, pokud je tabulka spravovaná tabulka HMS.
  • Runtime: Databricks Runtime 17.3 nebo vyšší
  • Oprávnění: OWNER nebo MANAGE oprávnění k tabulce a CREATE oprávnění pro EXTERNAL LOCATION

Výstraha

Souběžné zápisy do zdrojové tabulky a z katalogu Unity se nepodporují. Zodpovídáte za zakázání čtení a zápisů do zdrojové tabulky v externím katalogu a zajištění migrace úloh do nového katalogu před provedením převodu.

Syntaxe

Pokud chcete převést cizí tabulku Unity Catalog na externí, spusťte následující příkaz:

ALTER TABLE source_table SET EXTERNAL [DRY RUN]

Parametry

  • source_table

    Existující cizí tabulka v katalogu Unity. Cizí tabulky obsahují data a metadata spravovaná externím katalogem. Před převedením, pokud dojde k smazání zdrojové tabulky v externím katalogu, je cizí tabulka také zrušena v katalogu Unity. Po převodu tabulky na externí, vyřazení zdrojové tabulky v externím katalogu nemá vliv na externí tabulku katalogu Unity.

  • DRY RUN

    Po zadání zkontroluje, jestli se dá zdrojová tabulka upgradovat bez upgradu cílových tabulek. Příkaz vrátí DRY_RUN_SUCCESS, pokud je možné upgradovat tabulku.

Vrácení zpět

Pokud chcete migraci tabulky vrátit zpět, odstraňte tabulku a pak bude znovu federována jako cizí v další synchronizaci katalogu.

DROP TABLE catalog.schema.my_external_table;

Kontrola převodu

Potvrdit, že vaše cizí tabulka byla převedena na externí tabulku, lze ověřením v Katalog Exploreru. Před převodem se tabulka zobrazí jako Cizí a po převodu se zobrazí jako Externí.

Poznámka:

Spuštění DESCRIBE EXTENDED zobrazuje typ tabulky jako EXTERNAL jak před převodem, tak po něm. Důvodem je to, jak federace funguje, protože napodobuje chování spuštění tohoto příkazu v hive_metastore katalogu. K přesnému ověření převodu použijte Průzkumníka katalogu.

časté otázky

Můžu vytvářet tabulky i převádět tabulky v cizím katalogu?

Ano, externí nebo spravované tabulky můžete vytvořit v cizím katalogu. Chování závisí na konfiguraci schématu:

  • Pro schémata Glue nebo eHMS, nebo pro schémata se spravovaným umístěním v katalogu Unity: Pokud spustíte CREATE TABLE foreign_catalog.schema.table, vytvoří se spravovaná nebo externí tabulka v katalogu Unity. Tabulka není odeslána ani synchronizována s externím katalogem.
  • Pro schémata z interních připojení do metastore Hive: Pokud se pokusíte vytvořit tabulku v cizím schématu, dojde k vytvoření cizí tabulky a zároveň se vytvoří tabulka v hive_metastore.
  • Pro starší verzi metastoru Hive: Protože se jedná o federaci čtení a zápisu, pokud vytvoříte tabulku v cizím katalogu, vytvoří také tabulku v interním metastoru Hive.

Co když jsou moje cizí tabulky ve formátu SerDe?

U tabulek Parquet SerDe v AWS Glue je nutné před převodem na externí tabulku upravit metadata tabulky. Následující skript Pythonu používá knihovnu AWS boto3 k aktualizaci potřebných vlastností:

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!")

Co když jsou moje cizí tabulky založené na DBFS?

Při převodu tabulky, která je podporována DBFS, ukládáme aktuální mapování cesty DBFS na cloudovou cestu jako umístění externí cloudové cesty tabulky.

Můžu převést na úrovni schématu nebo katalogu?

Můžete iterovat přes tabulky ve svých schématech a převádět je jednotlivě, nebo využít projekt discoverx labs k převodu celých schémat nebo katalogů najednou.

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