Créer une table externe à partir de fichiers CSV

Big DataBeginner
Pratiquer maintenant

Introduction

Dans le premier lab Hive, une table préparée vous permettait d’interroger immédiatement les commandes. Le commerçant a maintenant fourni des fichiers CSV, mais un fichier présent dans le stockage n’est pas encore une table que Hive sait interroger. Vous devez décrire ses champs et identifier le répertoire contenant ses données.

Une table externe est une définition de table faisant référence à des données gérées séparément de cette définition. Son schéma indique les noms et les types des colonnes, et son LOCATION désigne les fichiers stockés. Créer la définition ne téléverse pas les fichiers et ne réécrit pas leur contenu. Hive conserve les métadonnées des tables dans son Metastore, tandis que les enregistrements restent dans le stockage.

Vous téléverserez deux sources CSV simples, associerez la première à un schéma explicite, basculerez l’association vers la seconde et supprimerez uniquement une définition de table externe jetable. L’expérience finale utilise des propriétés explicites de conservation des données dans la version de Hive de ce cours ; elle ne garantit pas que la suppression de toute table Hive préserve les fichiers. Les services et les entrées locales sont préparés indépendamment, et aucun cours Hadoop ni langage de programmation n’est requis. Utilisez le Terminal.

Examiner et téléverser les fichiers sources

Dans cette étape, vous examinerez le format CSV et copierez les deux fichiers fournis dans des répertoires HDFS distincts.

Commencez dans votre projet local :

cd /home/labex/project

Un fichier CSV sépare les champs par des virgules. Ces fichiers pédagogiques contiennent des valeurs simples, sans virgules internes, texte multiligne entre guillemets ou séparateurs échappés. Le format de table simple utilisé ici est choisi pour ces entrées ; ce n’est pas un analyseur universel pour tous les dialectes CSV.

La commande locale head -n 4 affiche les quatre premières lignes :

head -n 4 /home/labex/project/data/orders-a.csv

Vous devriez voir un en-tête suivi de trois enregistrements de commandes :

order_id,customer_id,product_id,quantity,unit_price,order_status,order_date
o1,c1,p1,2,10.00,paid,2026-10-14
o2,c2,p2,1,25.00,paid,2026-10-14
o3,c1,p1,1,10.00,pending,2026-10-14

Comptez les lignes terminées par un saut de ligne avec wc -l :

wc -l /home/labex/project/data/orders-a.csv /home/labex/project/data/orders-b.csv

La source A comporte sept lignes, mais seulement six enregistrements métier ; la source B comporte trois lignes, mais seulement deux enregistrements. L’en-tête ne doit pas devenir une ligne de commande.

HDFS est un système de fichiers distinct utilisé par le service Hive préparé. Le client hdfs dfs gère ses fichiers. -mkdir -p crée les répertoires HDFS nommés et les parents manquants :

hdfs dfs -mkdir -p /user/labex/hive-mapping/source-a /user/labex/hive-mapping/source-b

L’opération -put copie une source locale vers une destination HDFS, en conservant l’original intact :

hdfs dfs -put /home/labex/project/data/orders-a.csv /user/labex/hive-mapping/source-a/orders.csv

Téléversez la seconde source dans son propre répertoire :

hdfs dfs -put /home/labex/project/data/orders-b.csv /user/labex/hive-mapping/source-b/orders.csv

Un téléversement réussi n’affiche normalement rien. Une destination existante doit être examinée avant toute décision d’écrasement ; ne supprimez pas les données brutes simplement pour répéter une commande. Lisez le premier fichier HDFS avec -cat :

hdfs dfs -cat /user/labex/hive-mapping/source-a/orders.csv

Son en-tête et ses six enregistrements sont toujours présents. Le téléversement préserve les octets ; une définition de table indiquera à Hive comment les interpréter.

Définir la correspondance entre fichier et table

Dans cette étape, vous créerez une table externe avec des champs et types explicites, un emplacement de répertoire et une gestion des en-têtes.

L’ordre des champs de la source doit correspondre à l’ordre des colonnes de la table. Utilisez STRING pour les identifiants et le statut, INT pour une quantité entière, DECIMAL(10,2) pour un prix à virgule fixe et DATE pour la date au format ISO. Les prix décimaux évitent les approximations de la virgule flottante binaire dans les futurs calculs monétaires.

CREATE DATABASE IF NOT EXISTS crée l’espace de noms si nécessaire. CREATE EXTERNAL TABLE enregistre ensuite une définition de table. Les clauses de format indiquent du texte séparé par des virgules ; LOCATION nomme le répertoire, donc conservez les fichiers sans rapport et les sauvegardes à l’extérieur. Les deux propriétés ignorent une ligne d’en-tête par fichier et désactivent explicitement la purge des données de table externe lors d’un DROP dans cet environnement.

Enregistrez le fichier SQL complet. Comme dans le premier lab, le here-document du shell écrit littéralement les lignes jusqu’au délimiteur SQL final :

cat > /home/labex/project/queries/create-orders.sql <<'SQL'
CREATE DATABASE IF NOT EXISTS retail_mapping;
USE retail_mapping;
CREATE EXTERNAL TABLE raw_orders (
  order_id STRING,
  customer_id STRING,
  product_id STRING,
  quantity INT,
  unit_price DECIMAL(10,2),
  order_status STRING,
  order_date DATE
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION 'hdfs://localhost:9000/user/labex/hive-mapping/source-a'
TBLPROPERTIES ('skip.header.line.count'='1', 'external.table.purge'='false');
SQL

Exécutez-le avec Beeline. La connexion et l’option de fichier -f sont les mêmes que dans le premier lab :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true -f /home/labex/project/queries/create-orders.sql

Ce sont des instructions DDL (Data Definition Language, langage de définition des données) : des instructions SQL qui définissent des objets comme les tables. Les instructions DDL réussies créent des métadonnées plutôt que de renvoyer des lignes de commandes. Si la table existe déjà après une exécution terminée, examinez-la au lieu de la supprimer pour faire disparaître le message.

DESCRIBE FORMATTED inclut le type et l’emplacement de la table en plus de ses colonnes :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'DESCRIBE FORMATTED retail_mapping.raw_orders;'

Trouvez EXTERNAL_TABLE et l’emplacement se terminant par /hive-mapping/source-a. Il s’agit d’observations de métadonnées, pas d’une preuve que chaque enregistrement est correctement interprété. Utilisez aussi une requête. COUNT(*) compte les lignes de la table et fournit donc une vérification rapide de la correspondance. AS order_count donne un nom de colonne à ce résultat calculé, appelé un alias ; il ne renomme pas de champ source et ne modifie pas les enregistrements stockés :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'SELECT COUNT(*) AS order_count FROM retail_mapping.raw_orders; SELECT order_id, quantity, unit_price, order_date FROM retail_mapping.raw_orders ORDER BY order_id LIMIT 2;'

Le nombre doit être 6, et non les sept lignes de texte du fichier. Les deux premiers enregistrements doivent contenir les identifiants o1, o2, les quantités 2, 1, des prix numériquement égaux à 10.00, 25.00 et la date 2026-10-14. Vous avez vérifié à la fois la gestion de l’en-tête et des colonnes typées cohérentes.

Faire pointer la même table vers une nouvelle source

Dans cette étape, vous changerez l’emplacement de la table et prévoirez l’effet sur ses lignes sans déplacer aucun des fichiers sources.

La source B possède les mêmes champs, mais contient les commandes o7 et o8. Lisez le fichier stocké avant de modifier les métadonnées :

hdfs dfs -cat /user/labex/hive-mapping/source-b/orders.csv

Vous devriez voir son en-tête et deux enregistrements. Prévoyez le nombre de lignes de la table après l’avoir dirigée vers ce répertoire : deux, au lieu de six. ALTER TABLE ... SET LOCATION change la référence de répertoire dans la définition de table. Il ne copie pas les anciennes données dans le nouveau répertoire et ne fusionne pas les deux livraisons.

Enregistrez ce changement de métadonnées :

cat > /home/labex/project/queries/map-second-source.sql <<'SQL'
ALTER TABLE retail_mapping.raw_orders SET LOCATION 'hdfs://localhost:9000/user/labex/hive-mapping/source-b';
SQL

Exécutez-le :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true -f /home/labex/project/queries/map-second-source.sql

Examinez à nouveau les métadonnées et les données :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'DESCRIBE FORMATTED retail_mapping.raw_orders; SELECT COUNT(*) AS order_count FROM retail_mapping.raw_orders; SELECT order_id, quantity, unit_price FROM retail_mapping.raw_orders ORDER BY order_id;'

Trouvez le nouvel emplacement source-b, le nombre 2 et les lignes de o7 et o8. Leurs quantités sont 1 et 2, et leurs prix valent numériquement 50.00 et 15.00. Les définitions des colonnes n’ont pas changé ; seuls les fichiers lus à travers elles ont changé.

Lisez l’ancien fichier pour vérifier que le changement de correspondance ne l’a pas supprimé :

hdfs dfs -cat /user/labex/hive-mapping/source-a/orders.csv

Ses six enregistrements et son en-tête doivent toujours être présents. L’existence d’un fichier et sa visibilité dans une table sont des faits différents : la source A existe encore, même si cette table lit maintenant la source B.

Supprimer uniquement une définition de table jetable

Dans cette étape, vous créerez puis supprimerez une définition de table externe sur la première source conservée, tout en préservant les données et la table principale.

Supprimer une définition de table et supprimer ses données sont deux opérations différentes. Pour cette expérience, utilisez un nom séparé, disposable_orders, avec les propriétés explicites de conservation des données externes. Gardez raw_orders, qui correspond maintenant à la source B, disponible tout au long de l’exercice.

Créez la définition jetable sur la source A avec le même schéma connu :

cat > /home/labex/project/queries/create-disposable.sql <<'SQL'
CREATE EXTERNAL TABLE retail_mapping.disposable_orders (
  order_id STRING,
  customer_id STRING,
  product_id STRING,
  quantity INT,
  unit_price DECIMAL(10,2),
  order_status STRING,
  order_date DATE
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ','
STORED AS TEXTFILE
LOCATION 'hdfs://localhost:9000/user/labex/hive-mapping/source-a'
TBLPROPERTIES ('skip.header.line.count'='1', 'external.table.purge'='false');
SQL

Exécutez la définition :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex --silent=true -f /home/labex/project/queries/create-disposable.sql

Vérifiez que les deux noms de tables existent :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'SHOW TABLES IN retail_mapping;'

Vous devriez voir disposable_orders et raw_orders. DROP TABLE supprime une définition de table. Ici, il cible uniquement la table externe jetable, dont la propriété de purge est explicitement fausse :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'DROP TABLE retail_mapping.disposable_orders; SHOW TABLES IN retail_mapping;'

Seule raw_orders doit rester. Examinez maintenant le fichier source indépendamment :

hdfs dfs -cat /user/labex/hive-mapping/source-a/orders.csv

L’en-tête et les six enregistrements doivent rester présents. Ce comportement observé s’applique à cette configuration de table externe. Une table gérée ou une table externe ayant d’autres propriétés de purge peut supprimer les données lors de sa suppression ; ne généralisez pas cette expérience en règle universelle de suppression.

Confirmez que la table principale lit toujours la source B :

beeline -u 'jdbc:hive2://localhost:10000/default' -n labex -e 'SELECT order_id FROM retail_mapping.raw_orders ORDER BY order_id;'

Vous devriez toujours voir o7 et o8. Vous avez séparé trois opérations souvent confondues par les débutants : téléverser des octets, enregistrer ou modifier des métadonnées et supprimer une définition. Vous utiliserez ensuite ces lignes correctement interprétées pour filtrer des conditions et traiter les valeurs manquantes.

Résumé

Vous avez téléversé des sources CSV simples, déclaré l’ordre et les types de leurs champs, ignoré les en-têtes et enregistré une table externe dans un répertoire HDFS explicite. Vous avez vérifié les métadonnées et les enregistrements réels, puis modifié l’emplacement de la table sans déplacer les fichiers sources.

Enfin, vous avez supprimé une définition de table externe jetable avec des paramètres explicites de conservation et confirmé que les fichiers et la table principale restaient disponibles. Vous vous appuierez ensuite sur une correspondance fiable pour choisir des lignes et traiter les valeurs manquantes.