web-dev-qa-db-fra.com

Comment lire des CSV cités avec des valeurs NULL dans Amazon Athena

J'essaie de créer une table externe à Athena en utilisant un fichier CSV cité stocké sur S3. Le problème est que mon CSV contient des valeurs manquantes dans les colonnes qui doivent être lues comme INT. Exemple simple:

CSV:

id,height,age,name
1,,26,"Adam"
2,178,28,"Robert"

CRÉER UNE DÉFINITION DE TABLE:

CREATE EXTERNAL TABLE schema.test_null_unquoted (
  id INT,
  height INT,
  age INT,
  name STRING
)
ROW FORMAT 
SERDE 'org.Apache.hadoop.Hive.serde2.OpenCSVSerde'
WITH SERDEPROPERTIES (
'separatorChar' = ",",
'quoteChar' = '"',
'skip.header.line.count' = '1'
)
STORED AS TEXTFILE
LOCATION 's3://mybucket/test_null/unquoted/'

L'instruction CREATE TABLE Fonctionne correctement, mais dès que j'essaie d'interroger la table, je reçois Hive_BAD_DATA: Error parsing field value ''.

J'ai essayé de faire ressembler le CSV à ceci (citez une chaîne vide):

"id","height","age","name"
1,"",26,"Adam"
2,178,28,"Robert"

Mais ça ne marche pas.

J'ai essayé de spécifier 'serialization.null.format' = '' Dans SERDEPROPERTIES - ne fonctionne pas.

J'ai essayé de spécifier la même chose via TBLPROPERTIES ('serialization.null.format'='') - toujours rien.

Cela fonctionne, lorsque vous spécifiez toutes les colonnes comme STRING mais ce n'est pas ce dont j'ai besoin.

Par conséquent, la question est, y a-t-il de toute façon pour lire un CSV cité (la citation est importante car mes données réelles sont beaucoup plus complexes) à Athena avec une spécification de colonne correcte?

10
Mikolaj

Manière rapide et sale de gérer ces données:

CSV:

id,height,age,name
1,,26,"Adam"
2,178,28,"Robert"
3,123,34,"Bill, Comma"
4,183,38,"Alex"

DDL:

CREATE EXTERNAL TABLE stackoverflow.test_null_unquoted (
  id INT,
  height INT,
  age INT,
  name STRING
)
ROW FORMAT DELIMITED
 FIELDS TERMINATED BY ','
 LINES TERMINATED BY '\n' -- Or use Windows Line Endings
LOCATION 's3://XXXXXXXXXXXXX/'
TBLPROPERTIES ('skip.header.line.count'='1')
;

Le problème est qu'il ne gère pas les caractères de citation dans le dernier champ. Sur la base de la documentation fournie par AWS , cela a du sens comme LazySimpleSerDe étant donné ce qui suit de Hive .

Je soupçonne que la solution utilise le SerDe suivant org.Apache.hadoop.Hive.serde2.RegexSerDe.

Je travaillerai sur l'expression régulière plus tard.

Modifier:

Regex comme promis:

CREATE EXTERNAL TABLE stackoverflow.test_null_unquoted (
  id INT,
  height INT,
  age INT,
  name STRING
)
ROW FORMAT SERDE 'org.Apache.hadoop.Hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(.*),(.*),(.*),\"(.*)\""
)
LOCATION 's3://XXXXXXXXXXXXXXX/'
TBLPROPERTIES ('skip.header.line.count'='1') -- Does not appear to work
;

enter image description here

Remarque: RegexSerDe ne semble pas fonctionner correctement avec TBLPROPERTIES ('skip.header.line.count'='1'). Cela pourrait être dû à la version Hive utilisée par Athena ou SerDe. Dans votre cas, vous pouvez probablement exclure simplement les lignes où ID IS NULL.

Lectures complémentaires:

Stackoverflow - supprime les guillemets environnants des champs lors du chargement des données dans Hive

Athena - OpenCSVSerDe pour le traitement CSV

5
Zerodf