Partilhar via


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

Importante

Esta funcionalidade encontra-se na Pré-visualização Pública e só está disponível para clientes participantes neste momento. Para participar na pré-visualização, candidate-se preenchendo este formulário. Esse recurso suporta apenas a conversão de tabelas estrangeiras 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 SET EXTERNAL

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

  • Manter o histórico da tabela
  • Manter as mesmas configurações de tabela, incluindo o mesmo nome, definições, permissões e vistas.

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.
  • Tempo de execução: Databricks Runtime 17.3 ou superior
  • Permissões: OWNER ou MANAGE permissões na tabela e CREATE permissão na EXTERNAL LOCATION

Advertência

As gravações simultâneas na tabela de origem e no Catálogo Unity não são suportadas. 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 a tabela estrangeira do Unity Catalog numa tabela externa do Unity Catalog, execute o seguinte comando:

ALTER TABLE source_table SET EXTERNAL [DRY RUN]

Parâmetros

  • source_table

    Uma tabela estrangeira existente no Catálogo Unity. As tabelas estrangeiras contêm dados e metadados gerenciados por um catálogo externo. Antes da conversão, se você soltar a tabela de origem no catálogo externo, a tabela estrangeira também será descartada no Unity Catalog. Depois que a tabela é convertida em externa, soltar 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 retorna DRY_RUN_SUCCESS se uma tabela puder ser atualizada.

Reversão

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

DROP TABLE catalog.schema.my_external_table;

Verificar conversão

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

Observação

A execução DESCRIBE EXTENDED mostra o tipo de tabela como EXTERNAL antes e depois da conversão. Isso se deve ao funcionamento da Federação, pois ela imita o comportamento da execução desse comando no hive_metastore catálogo. Para verificar a conversão com precisão, use o Gerenciador de Catálogos.

FAQ

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 gerido definido no Catálogo Unity: Se executar CREATE TABLE foreign_catalog.schema.table, isto criará uma tabela do Catálogo Unity gerida ou externa. A tabela não é enviada por push ou sincronizada com o catálogo externo.
  • Para esquemas de conexões internas do metastore do Hive: Se você tentar criar uma tabela em um esquema externo, ela ainda criará uma tabela estrangeira e também criará uma tabela no hive_metastore.
  • Para o metastore Hive de espaço de trabalho legado: Como é uma federação de leitura e gravação, se se criar uma tabela no catálogo estrangeiro, também é criada uma tabela no metastore interno do Hive.

E se as minhas tabelas externas estiverem em 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 da 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 as minhas tabelas estrangeiras forem apoiadas por DBFS?

Ao converter uma tabela suportada por DBFS, armazenamos o mapeamento atual do caminho do DBFS para o caminho da nuvem, definindo-o como a localização do caminho da tabela externa na nuvem.

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

Você pode percorrer suas tabelas nos seus esquemas para converter cada uma individualmente, ou usar o projeto discoverx labs para converter todo um esquema ou catálogo de uma só vez.

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