Aller au contenu principal

Convertir une table étrangère en une table externe Unity Catalog

info

Aperçu public

Cette fonctionnalité est en Aperçu public. Cette fonctionnalité ne prend en charge que la conversion des tables étrangères fédérées à l'aide de HMS et Glue Federation.

Cette page décrit comment utiliser SET EXTERNAL pour convertir une table étrangère en une table externe.

SET EXTERNAL Présentation

Utilisez la fonctionnalité SET EXTERNAL pour convertir une table externe en table EXTERNAL Unity Catalog dans Databricks. SET EXTERNAL offre les avantages suivants :

  • Conservation de l’historique des tables
  • Le maintien des mêmes configurations de table, y compris le même nom, les mêmes paramètres, les mêmes autorisations et les mêmes vues.

Prérequis

  • Format de données : Le format de données de la table étrangère doit être l'un des suivants :

    • Delta
    • Parquet
    • ORC
    • Avro
    • JSON
    • CSV
    • Texte
  • Type de table : Le type de table HMS doit être une table HMS externe. La commande échoue si la table est une table HMS gérée.

  • Runtime : Databricks Runtime 17.3 ou version supérieure

  • Autorisations : OWNER ou MANAGE autorisations sur la table et CREATE autorisation sur le/la EXTERNAL LOCATION

attention

Les écritures concurrentes vers la table source et depuis Unity Catalog ne sont pas prises en charge. Vous êtes responsable de la désactivation des lectures et écritures vers la table source dans le catalogue externe et de vous assurer que les charges de travail ont migré vers le nouveau catalogue avant d'effectuer la conversion.

Syntaxe

Pour convertir votre table externe Unity Catalog en table externe Unity Catalog, exécutez la commande suivante :

SQL
ALTER TABLE source_table SET EXTERNAL [DRY RUN]

parameter

  • table source

    Une table étrangère existante dans Unity Catalog. Les tables étrangères contiennent des données et des métadonnées gérées par un catalogue externe. Avant la conversion, si vous supprimez la table source dans le catalogue externe, la table étrangère est également supprimée dans Unity Catalog. Une fois la table convertie en table externe, la suppression de la table source dans le catalogue externe n’affecte pas la table externe de Unity Catalog.

  • DRY RUN

    Lorsqu’il est spécifié, vérifie si la table source peut être mise à niveau sans mettre à niveau les tables cible. La commande renvoie DRY_RUN_SUCCESS si une table peut être mise à niveau.

Restauration

Pour annuler la migration de la table, supprimez la table, qui sera ensuite refédérée en tant qu'étrangère lors de la prochaine synchronisation du catalogue.

SQL
DROP TABLE catalog.schema.my_external_table;

Vérifier la conversion

Vous pouvez confirmer que votre table étrangère a été convertie en table externe en vérifiant dans l'Explorateur de catalogue. Avant la conversion, la table apparaît comme Étrangère , et après la conversion, elle apparaît comme Externe .

remarque

L'exécution de DESCRIBE EXTENDED affiche le type de table comme EXTERNAL avant et après la conversion. Cela est dû au fonctionnement de la Fédération, car elle imite le comportement de l'exécution de cette commande sur le catalogue hive_metastore. Pour vérifier précisément la conversion, utilisez l'Explorateur de catalogue.

FAQ

Puis-je créer des tables et convertir des tables dans un catalogue étranger ?

Oui, vous pouvez créer des tables externes ou gérées dans un catalogue étranger. Le comportement dépend de la configuration du schéma :

  • Pour les schémas Glue ou eHMS , ou pour les schémas avec un emplacement géré défini dans Unity Catalog : si vous exécutez CREATE TABLE foreign_catalog.schema.table, cela crée une table gérée ou externe de Unity Catalog. La table n'est pas poussée ni synchronisée vers le catalogue externe.
  • Pour les schémas provenant de connexions internes au Hive metastore : si vous essayez de créer une table dans un schéma externe, une table externe est quand même créée et une table est également créée dans hive_metastore.
  • Pour le Workspace Hive metastore d'un Workspace hérité : puisqu'il s'agit d'une fédération en lecture-écriture, si vous créez une table dans le catalogue étranger, elle crée également une table dans le Hive metastore interne.

Et si mes tables étrangères sont au format SerDe ?

Pour les tables Parquet SerDe dans AWS Glue, vous devez modifier les métadonnées de la table avant de la convertir en table externe. Le script Python suivant utilise la bibliothèque boto3 AWS pour mettre à jour les propriétés nécessaires :

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

Et si mes tables externes sont prises en charge par DBFS ?

Lors de la conversion d'une table adossée à DBFS, nous stockons le mappage actuel du chemin DBFS vers le chemin cloud en tant qu'emplacement du chemin cloud de la table externe.

Puis-je convertir au niveau du schéma ou du catalogue ?

Vous pouvez parcourir vos tables dans vos schémas pour les convertir individuellement, ou utiliser le projet discoverx labs pour convertir des schémas ou des catalogues entiers en une seule fois :

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