Поделиться через


Преобразование внешней таблицы в внешнюю таблицу каталога Unity

Это важно

Эта функция доступна в общедоступной предварительной версии и доступна только для участвующих клиентов в настоящее время. Чтобы принять участие в предварительной версии, заполните заявку, заполнив эту форму. Эта функция поддерживает только преобразование внешних таблиц, объединённых с помощью федерации HMS и Glue Federation.

На этой странице описывается, как с помощью SET EXTERNAL преобразовать внешнюю таблицу в внешнюю таблицу.

SET EXTERNAL обзор

Используйте функцию SET EXTERNAL для преобразования внешней таблицы в таблицу каталога EXTERNAL Unity в Azure Databricks. SET EXTERNAL предоставляет следующие преимущества:

  • Сохранение истории таблицы
  • Сохранение одинаковых конфигураций таблицы, включая то же имя, параметры, разрешения и представления.

Предпосылки

  • Формат данных: формат данных внешней таблицы должен быть одним из следующих:
    • Delta
    • Parquet
    • ORC
    • Avro
    • JSON
    • CSV
    • ТЕКСТ
  • Тип таблицы: тип таблицы HMS должен быть внешней таблицей HMS. Команда завершается ошибкой, если таблица является управляемой таблицей HMS.
  • Среда выполнения: Databricks Runtime 17.3 или более поздней версии
  • Разрешение: OWNER или MANAGE разрешение на таблицу и CREATE разрешение для EXTERNAL LOCATION

Предупреждение

Одновременные записи в исходную таблицу и из каталога Unity не поддерживаются. Вы несете ответственность за отключение операций чтения и записи в исходную таблицу во внешнем каталоге и обеспечение миграции рабочих нагрузок в новый каталог перед выполнением преобразования.

Синтаксис

Чтобы преобразовать внешнюю таблицу каталога Unity в внешнюю таблицу каталога Unity, выполните следующую команду:

ALTER TABLE source_table SET EXTERNAL [DRY RUN]

Параметры

  • таблица_источника

    Существующая внешняя таблица в Unity Catalog. Внешние таблицы содержат данные и метаданные, управляемые внешним каталогом. Перед преобразованием, если удалить исходную таблицу во внешнем каталоге, внешняя таблица также удаляется в каталоге Unity. После преобразования таблицы во внешнюю, удаление исходной таблицы во внешнем каталоге не влияет на внешнюю таблицу каталога Unity.

  • DRY RUN

    При указании проверяет, можно ли обновить исходную таблицу без обновления целевых таблиц. Команда возвращает DRY_RUN_SUCCESS, если таблицу можно обновить.

Откат

Чтобы откатить миграцию таблицы, удалите таблицу, а затем она вновь федеративная как внешняя в следующей синхронизации каталога.

DROP TABLE catalog.schema.my_external_table;

Проверка преобразования

Вы можете убедиться, что внешняя таблица была преобразована в внешнюю таблицу, выполнив проверку в обозревателе каталогов. Перед преобразованием таблица отображается как чужой и после преобразования отображается как внешний.

Замечание

При выполнении DESCRIBE EXTENDED отображается тип таблицы как EXTERNAL до, так и после преобразования. Это связано с тем, как работает федерация, так как она имитирует поведение выполнения этой команды в каталоге hive_metastore . Чтобы точно проверить преобразование, используйте обозреватель каталогов.

Часто задаваемые вопросы

Можно ли создавать таблицы, а также преобразовывать таблицы в внешнем каталоге?

Да, можно создать внешние или управляемые таблицы в внешнем каталоге. Поведение зависит от конфигурации схемы:

  • Для схем Glue или eHMS или схем с управляемым расположением, заданным в каталоге Unity: при выполнении CREATE TABLE foreign_catalog.schema.tableэто создает управляемую или внешнюю таблицу каталога Unity. Таблица не отправляется или не синхронизируется с внешним каталогом.
  • Для схем из внутренних подключений метахранилища Hive: если попытаться создать таблицу в другой схеме, она все равно создаст таблицу в другой схеме, а также создаст таблицу в hive_metastore.
  • Для устаревшего хранилища метаданных Hive рабочей области: поскольку имеется возможность чтения и записи в рамках федерации, создание таблицы в чужом каталоге также создаёт таблицу во внутреннем хранилище метаданных Hive.

Что делать, если мои внешние таблицы находятся в формате SerDe?

Для таблиц Parquet SerDe в AWS Glue необходимо изменить метаданные таблицы перед преобразованием во внешнюю таблицу. Следующий скрипт Python использует библиотеку boto3 AWS для обновления необходимых свойств:

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 для одновременного преобразования целых схем или каталогов:

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