Saltar al contenido

¿Cómo soluciono el error «Unable to infer schema» en AWS Glue?

4 minutos de lectura
0

Aparece el error «Unable to infer schema» cuando ejecuto mi trabajo de AWS Glue para procesar los archivos de Parquet u ORC que almaceno en Amazon Simple Storage Service (Amazon S3).

Descripción corta

Los archivos de Parquet u ORC deben seguir un formato de ruta de partición key=value al estilo de Hive. Si, en cambio, los archivos utilizan una estructura de rutas jerárquica, AWS Glue no entiende el esquema y produce un error.

Por ejemplo, si tu trabajo de AWS Glue procesa archivos de s3://s3-bucket/parquet-data/, los archivos deben usar el siguiente formato particionado:

s3://s3-bucket/parquet-data/year=2018/month=10/day=10/file1.parquet

Si los archivos utilizan el siguiente formato no particionado, se produce un error en el trabajo de AWS Glue:

s3://s3-bucket/parquet-data/year/month/day/file1.parquet

Resolución

Para resolver el error «Unable to infer schema» en AWS Glue, utiliza uno de los siguientes métodos para tu caso práctico.

Reestructuración de los datos

Copia los archivos en un nuevo bucket de S3 y usa rutas particionadas al estilo Hive. A continuación, ejecuta el trabajo.

Sustitución de los nombres de las columnas de partición por asteriscos

Si no puedes reestructurar los datos, crea el DynamicFrame directamente desde Amazon S3. Utiliza asteriscos (*) en lugar de los nombres de las columnas de partición. AWS Glue incluye solo los datos del DynamicFrame, no las columnas de partición.

Por ejemplo, si almacenas tus archivos en un bucket de S3 con la ruta de archivo s3://s3-bucket/parquet-data/year/month/day/files.parquet, utiliza el siguiente DynamicFrame:

dynamic_frame0 = glueContext.create_dynamic_frame_from_options(
    's3',
    connection_options={'paths': ['s3://s3-bucket/parquet-data/*/*/*']},
    format='parquet',
    transformation_ctx='dynamic_frame0'
)

Uso de una transformación de clase de mapa para agregar columnas de partición

Para incluir las columnas de partición en el DynamicFrame, lee los datos en el DataFrame y agrega una columna para la ruta del archivo de Amazon S3. A continuación, aplica una transformación de clase de mapa.

Código de ejemplo: 

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 input_file_name

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

Nota: Sustituye las rutas de S3 de ejemplo por tus rutas de S3 y personaliza las columnas de partición para tu caso práctico.

Resolución de archivos o prefijos que no existen

Si no hay ningún archivo en la ruta, comprueba si los has eliminado o archivado. Si los archivos usan un prefijo diferente, actualiza el parámetro connection_options en tu script de AWS Glue para que apunte a la ruta correcta. Compruebe también si la tabla del catálogo hace referencia a una ubicación de S3 que falta o está desactualizada. Si la tabla indica que faltan archivos, el trabajo falla porque no hay datos que procesar.

Resolución de problemas cuando un trabajo con el parámetro de marcador de trabajo analiza archivos antiguos 

Cuando utilizas un marcador de trabajo, AWS Glue realiza un seguimiento de los archivos procesados anteriormente y omite los archivos con marcas de tiempo anteriores. Si el trabajo no encuentra nuevos archivos aptos, se produce un error porque no hay datos que procesar.

Para solucionar este problema, toma las siguientes medidas:

  • Confirma que las marcas de tiempo modificadas de los archivos estén dentro del intervalo esperado.
  • Desactiva los marcadores para volver a procesar todos los archivos.
  • Cambia el nombre de los archivos o actualízalos para que tengan las marcas de tiempo más recientes de la última modificación, de modo que AWS Glue los detecte como archivos nuevos y los incluya en la próxima ejecución.

Información relacionada

Administración de particiones para la salida de ETL en AWS Glue

OFICIAL DE AWSActualizada hace un año