Compartilhar via


Converter uma tabela estrangeira em uma tabela externa do Catálogo do Unity

Importante

Esse recurso está em Visualização Pública e só está disponível para clientes participantes no momento. Para participar da versão prévia, inscreva-se preenchendo este formulário. Este recurso oferece suporte apenas à conversão de tabelas externas federadas usando HMS e Glue Federation.

Esta página descreve como usar SET EXTERNAL para converter uma tabela estrangeira em uma tabela externa.

visão geral do SET EXTERNAL

Use o SET EXTERNAL recurso para converter uma tabela estrangeira em uma tabela do Catálogo EXTERNAL do Unity no Azure Databricks. SET EXTERNAL oferece os seguintes benefícios:

  • Retendo o histórico da tabela
  • Mantendo as mesmas configurações de tabela, incluindo o mesmo nome, configurações, permissões e exibições.

Pré-requisitos

  • Formato de dados: o formato de dados da tabela estrangeira deve ser um dos seguintes:
    • Delta
    • Parquet
    • ORC
    • Avro
    • JSON
    • CSV
    • TEXTO
  • Tipo de tabela: o tipo de tabela HMS deve ser uma tabela HMS externa. O comando falhará se a tabela for uma tabela HMS gerenciada.
  • Runtime: Databricks Runtime 17.3 ou superior
  • Permissões: OWNER ou MANAGE permissões na tabela e CREATE permissão no EXTERNAL LOCATION

Aviso

Não há suporte para escritas simultâneas na tabela de origem e no Unity Catalog. Você é responsável por desabilitar leituras e gravações na tabela de origem no catálogo externo e garantir que as cargas de trabalho tenham migrado para o novo catálogo antes de executar a conversão.

Sintaxe

Para converter sua tabela estrangeira do Catálogo do Unity para ser externa do Catálogo do Unity, execute o seguinte comando:

ALTER TABLE source_table SET EXTERNAL [DRY RUN]

Parâmetros

  • tabela_fonte

    Uma tabela estrangeira existente no Catálogo do Unity. As tabelas estrangeiras contêm dados e metadados gerenciados por um catálogo externo. Antes da conversão, se você excluir a tabela de origem no catálogo externo, a tabela externa também será excluída no Unity Catalog. Depois que a tabela é convertida em externa, excluir a tabela de origem no catálogo externo não afeta a tabela externa do Unity Catalog.

  • DRY RUN

    Quando especificado, verifica se a tabela de origem pode ser atualizada sem atualizar as tabelas de destino. O comando retornará DRY_RUN_SUCCESS se uma tabela puder ser atualizada.

Reversão

Para reverter a migração de tabela, solte a tabela e ela será federada novamente como estrangeira na próxima sincronização de catálogo.

DROP TABLE catalog.schema.my_external_table;

Verificar conversão

Você pode confirmar se sua tabela estrangeira foi convertida em uma tabela externa verificando no Catalog Explorer. Antes da conversão, a tabela é exibida como Estrangeira e, após a conversão, ela é mostrada como Externa.

Observação

A execução DESCRIBE EXTENDED mostra o tipo de tabela como EXTERNAL antes e depois da conversão. Isso ocorre devido a como a Federação funciona, pois imita o comportamento de executar esse comando no hive_metastore catálogo. Para verificar com precisão a conversão, use o Gerenciador de Catálogos.

perguntas frequentes

Posso criar tabelas, bem como converter tabelas em um catálogo estrangeiro?

Sim, você pode criar tabelas externas ou gerenciadas em um catálogo estrangeiro. O comportamento depende da configuração do esquema:

  • Para esquemas glue ou eHMS ou para esquemas com um local gerenciado definido no Catálogo do Unity: Se você executar CREATE TABLE foreign_catalog.schema.table, isso criará uma tabela gerenciada ou externa do Catálogo do Unity. A tabela não é enviada por push ou sincronizada para o catálogo externo.
  • Para esquemas de conexões metastore internas do Hive: Se você tentar criar uma tabela em um esquema externo, ela ainda criará uma tabela estrangeira e também criará uma tabela em hive_metastore.
  • Para o metastore do Hive do workspace legado: Como ele suporta federação de leitura e escrita, ao criar uma tabela no catálogo estrangeiro, uma tabela também será criada no metastore interno do Hive.

E se minhas tabelas estrangeiras estiverem no formato SerDe?

Para tabelas Parquet SerDe no AWS Glue, você deve modificar os metadados da tabela antes de converter em uma tabela externa. O script Python a seguir usa a biblioteca boto3 do AWS para atualizar as propriedades necessárias:

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

E se minhas tabelas estrangeiras forem apoiadas por DBFS?

Ao converter uma tabela baseada em DBFS, armazenamos o mapeamento atual do caminho do DBFS para o caminho na nuvem como a localização do caminho de nuvem da tabela externa.

Posso converter no nível do esquema ou do catálogo?

Você pode iterar por suas tabelas em seus esquemas para converter cada uma individualmente, ou utilizar o DiscoverX Labs Project para converter esquemas ou catálogos inteiros de uma só vez.

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