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! 😉
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 usarResolveChoice.apply(frame = raw_df, choice = "cast:long")
para asegurarte de que todos los valores en la columnaid
se conviertan en longs.Esto debería solucionar el problema que estás experimentando y permitirte analizar todos los valores como tipo long.