web-dev-qa-db-fra.com

CSV Hive Load avec des virgules dans les champs cités

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.

40
Martijn Lenderink

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. .

28
Lorand Bendig

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
29
libjack

À 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 )

20
wrschneider

conserver le délimiteur entre guillemets simples cela fonctionnera.

ROW FORMAT DELIMITED 
FIELDS TERMINATED BY ','
LINES TERMINATED BY '\n';

Ça va marcher

0
suyash

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é.

0
Mantej Singh