2017-10-10 11 views
0

J'ai une image comme ci-dessous.Évitez de perdre le type de données pour les données partitionnées lorsque vous écrivez à partir de Spark

itemName, itemCategory 
Name1, C0 
Name2, C1 
Name3, C0 

Je voudrais enregistrer cette dataframe sous forme de fichier parquet cloisonné:

df.write.mode("overwrite").partitionBy("itemCategory").parquet(path) 

Pour ce dataframe, quand je lis les données de retour, il aura chaîne du type de données pour itemCategory.

Cependant, parfois, j'ai des données d'autres locataires comme ci-dessous.

itemName, itemCategory 
Name1, 0 
Name2, 1 
Name3, 0 

Dans ce cas, après avoir été écrit comme partition, lu en arrière, la trame de données résultante aura Int pour le type de itemCategory de données.

Le fichier de parquet contient les métadonnées qui décrivent le type de données. Comment puis-je spécifier le type de données pour la partition afin qu'il soit relu en tant que chaîne au lieu de Int?

+0

Est-il correct de supposer que lorsque vous lisez dans le « à d'autres moments » dataframes qu'il devient lu dans un CSV ou un format de fichier qui nécessite le type à déduire? – ayplam

+0

Non, les fichiers sont en format parquet, donc les types de données ne sont pas déduits sauf pour les clés de partition. – suriyanto

Répondre

0

Comme partitionBy itemCategory, ces données seront stockées dans la structure du fichier et non dans les fichiers CSV réels. Je suppose que Spark déduire le type de données en fonction des valeurs, si toutes les valeurs sont des entiers, le type de colonne sera int.

Une solution simple serait de jeter la colonne à StringType après avoir lu les données:

import spark.implicits._ 
df.withColumn("itemCategory", $"itemCategory".cast(StringType)) 

Une autre option serait de dupliquer la colonne elle-même. Ensuite, l'une des colonnes sera utilisée pour le partitionnement et, par conséquent, sera enregistrée dans la structure du fichier. Cependant, l'autre colonne dupliquée serait enregistrée normalement dans le fichier parquet. Pour faire un double utilisez simplement:

df.withColumn("itemCategoryCopy", $"itemCategory") 
+0

Merci pour la réponse. Malheureusement, j'ai simplifié le problème dans la question. J'ai un lecteur de parquet générique qui lit le fichier dans la base de données par partition demandée, donc ce sera un défi de devoir introduire cette logique spécifique. – suriyanto

+0

@suriyanto Je vois, j'ai ajouté une solution alternative qui pourrait peut-être vous aider, même si la solution n'est pas très élégante. – Shaido