Ma tâche AWS Glue échoue avec l'une des exceptions suivantes :
« AnalysisException: u'Unable to infer schema for Parquet. It must be specified manually » (AnalysisException : Impossible d'inférer le schéma pour Parquet. Il doit être défini manuellement.)
« AnalysisException: u'Unable to infer schema for ORC. It must be specified manually » (AnalysisException : Impossible d'inférer le schéma pour Parquet. Il doit être défini manuellement.)
Brève description
Cette erreur se produit généralement lorsqu'AWS Glue essaie de lire un fichier Parquet ou ORC qui n'est pas stocké dans un chemin partitionné de type Apache Hive avec la structure key=val. AWS Glue s'attend à ce que les fichiers sources Amazon Simple Storage Service (Amazon S3) se trouvent dans des paires clé-valeur. Par exemple, si la tâche AWS Glue traite les fichiers dans s3://s3-bucket/parquet-data/, les fichiers doivent avoir la structure de partition suivante :
s3://s3-bucket/parquet-data/year=2018/month=10/day=10/file1.parquet
Si les fichiers Parquet ou ORC sont stockés dans une structure hiérarchique, la tâche AWS Glue échoue avec l'exception « Unable to infer schema » (Impossible d'inférer le schéma). Exemple :
s3://s3-bucket/parquet-data/year/month/day/file1.parquet
Résolution
Utilisez l'une des méthodes suivantes pour éliminer l'erreur.
Restructurer vos données
Copiez les fichiers vers un nouveau compartiment S3 et utilisez des chemins partitionnés de type Hive. Réexécutez la tâche.
Remplacer les noms des colonnes de partition par des astérisques
Si la restructuration de vos données n'est pas possible, créez le DynamicFrame directement depuis Amazon S3. Dans le chemin Amazon S3, remplacez tous les noms des colonnes de partition par des astérisques (*). Lorsque vous utilisez cette solution, AWS Glue n'inclut pas les colonnes de partition dans le DynamicFrame ; il inclut uniquement les données.
Supposons que vos fichiers sont stockés dans un compartiment S3 avec la structure de partition suivante :
s3://s3-bucket/parquet-data/year/month/day/files.parquet
Pour traiter tous les fichiers dans le chemin s3://s3-bucket/parquet-data/, créez le DynamicFrame :
dynamic_frame0 = glueContext.create_dynamic_frame_from_options('s3',connection_options={'paths':['s3://s3-bucket/parquet-data/*/*/*'],},format="parquet",transformation_ctx = "dynamic_frame0")
Utiliser une transformation de mappe pour ajouter des colonnes de partition
Pour inclure les colonnes de partition dans le DynamicFrame, créez un DataFrame, puis ajoutez une colonne pour le chemin de fichier Amazon S3. Ensuite, créez le DynamicFrame et appliquez une transformation de mappe pour ajouter les colonnes de partition, comme indiqué dans l'exemple suivant. Avant d'utiliser l'exemple de code, remplacez les chemins Amazon S3 et saisissez les noms des colonnes de partition en utilisant les valeurs d'index correctes.
import sys
from awsglue.transforms import *
from awsglue.utils import getResolvedOptions
from pyspark.context import SparkContext
from awsglue.context import GlueContext
from awsglue.job import Job
from awsglue.dynamicframe import DynamicFrame
from pyspark.sql.functions import *
args = getResolvedOptions(sys.argv, ['JOB_NAME'])
sc = SparkContext()
glueContext = GlueContext(sc)
spark = glueContext.spark_session
job = Job(glueContext)
job.init(args['JOB_NAME'], args)
df= spark.read.parquet("s3://s3-bucket/parquet-data/*/*/*")
modified_df = df.withColumn('partitions_column',input_file_name())
dyf_0 = DynamicFrame.fromDF(modified_df, glueContext, "dyf_0")
def modify_col(x):
if x['partitions_column']:
new_columns = x['partitions_column'].split('/')
x['year'],x['month'],x['day'] = new_columns[4],new_columns[5],new_columns[6]
del x['partitions_column']
return x
modified_dyf = Map.apply(dyf_0,f=modify_col)
datasink2 = glueContext.write_dynamic_frame.from_options(frame =modified_dyf , connection_type = "s3", connection_options = {"path": "s3://my-output-bucket/output/","partitionKeys": ["year","month","day"]}, format = "parquet", transformation_ctx = "datasink2")
Pour plus d'informations sur l'application des transformations de mappe, consultez Classe de mappe.
Informations connexes
Gestion des partitions pour la sortie ETL dans AWS Glue