es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

AWS Glue crea una estructura cuando está presente el tipo de dato “long”.

Tengo un trabajo de Glue que lee un montón de archivos JSON de S3, crea un DynamicFrame y escribe el resultado en otro bucket de S3.

De esos archivos estoy seleccionando un campo id. Hasta hace poco, eso era un número pequeño y podía caber en un IntegerType de Spark (máximo: 2147483647). Ahora estoy empezando a ver números más grandes que deberían ser de tipo LongType.

Creando el DynamicFrame en Glue:

data_source = glueContext.create_dynamic_frame.from_options(
    connection_type="s3",
    connection_options={"paths": paths},
    format='json',
    transformation_ctx='data_source',
    format_options={"jsonPath": "$[*]"}
)

Leyendo los campos seleccionados:

df = SelectFields.apply(frame=data_source, paths=['id', ...])
df.toDF().printSchema()

El problema: Glue crea una struct en lugar de un long y eso arruina todo el trabajo.

root
 |-- id: struct (nullable = true)
 |    |-- int: int (nullable = true)
 |    |-- long: bigint (nullable = true)

Ejemplo: para un id con valor 5.000.000.000.000, la struct es [, 5000000000000] y para un id con valor 1.000.000, la struct es [1000000,].

Pregunta: ¿cómo puedo evitar que Glue haga esto? Quiero convertirlo todo a tipo long.

¡Gracias!

Actualización

Parece que algunos registros fueron procesados incluso si el valor del id era claramente un long. Así que parece que no siempre (?) Glue crea la struct.

Otra actualización

Parece que es un comportamiento esperado de Glue cuando siente que no puede determinar el tipo de datos real. Por eso existe esta clase ResolveChoice que te permite seleccionar un valor predeterminado. https://docs.aws.amazon.com/glue/latest/dg/aws-glue-api-crawler-pyspark-transforms-ResolveChoice.html

Usar esta clase para elegir el tipo que quiero resolvió mi problema. Por ejemplo, si tengo un id = [long=None, int=10] o id = [long=10, int=None] (por el bien del ejemplo), usar df = ResolveChoice.apply(frame=raw_df, choice="cast:long") me dará para ambos casos id=10 y tipo long.

¡Espero que esto ayude a otros! 😉

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para evitar que Glue cree una estructura en lugar de un long, puedes usar la clase ResolveChoice en las transformaciones de PySpark. Esta clase te permite seleccionar un valor predeterminado para una columna, incluyendo su tipo de datos.

    Por ejemplo, si tienes una columna id que puede contener enteros o longs, puedes usar ResolveChoice.apply(frame = raw_df, choice = "cast:long") para asegurarte de que todos los valores en la columna id se conviertan en longs.

    Esto debería solucionar el problema que estás experimentando y permitirte analizar todos los valores como tipo long.

Comments are closed.