J'essaye de charger un fichier CSV dans une table Hive comme ceci:
CREATE TABLE mytable
(
num1 INT,
text1 STRING,
num2 INT,
text2 STRING
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ",";
LOAD DATA LOCAL INPATH '/data.csv'
OVERWRITE INTO TABLE mytable;
Le csv est délimité par une virgule (,) et ressemble à ceci:
1, "some text, with comma in it", 123, "more text"
Cela retournera des données corrompues puisqu'il y a un ',' dans la première chaîne.
Est-il possible de définir un délimiteur de texte ou de faire en sorte que Hive ignore le ',' dans les chaînes?
Je ne peux pas changer le délimiteur du fichier csv car il est extrait d'une source externe.
Le problème est que Hive
ne gère pas les textes cités. Vous devez soit pré-traiter les données en modifiant le délimiteur entre les champs (par exemple: avec un travail de streaming Hadoop), soit vous pouvez également essayer d'utiliser un CSV SerDe personnalisé qui utilise OpenCSV pour analyser les fichiers. .
Si vous pouvez recréer ou analyser vos données d'entrée, vous pouvez spécifier un caractère d'échappement pour CREATE TABLE:
ROW FORMAT DELIMITED FIELDS TERMINATED BY "," ESCAPED BY '\\';
Acceptera cette ligne comme 4 champs
1,some text\, with comma in it,123,more text
À partir de Hive 0.14, le CSV SerDe fait partie de l’installation standard de Hive.
ROW FORMAT SERDE 'org.Apache.hadoop.Hive.serde2.OpenCSVSerde'
(Voir: https://cwiki.Apache.org/confluence/display/Hive/CSV+Serde )
conserver le délimiteur entre guillemets simples cela fonctionnera.
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';
Ça va marcher
Ajouter une barre oblique arrière dans les champs TERMINÉS PAR '\;'
Par exemple:
CREATE TABLE demo_table_1_csv
COMMENT 'my_csv_table 1'
ROW FORMAT DELIMITED
FIELDS TERMINATED BY '\;'
LINES TERMINATED BY '\n'
STORED AS TEXTFILE
LOCATION 'your_hdfs_path'
AS
select a.tran_uuid,a.cust_id,a.risk_flag,a.lookback_start_date,a.lookback_end_date,b.scn_name,b.alerted_risk_category,
CASE WHEN (b.activity_id is not null ) THEN 1 ELSE 0 END as Alert_Flag
FROM scn1_rcc1_agg as a LEFT OUTER JOIN scenario_activity_alert as b ON a.tran_uuid = b.activity_id;
Je l'ai testé et cela a fonctionné.