

# Administración de particiones para la salida de ETL en AWS Glue
<a name="aws-glue-programming-etl-partitions"></a>

La creación de particiones es una importante técnica para organizar conjuntos de datos de manera que se puedan consultar de forma eficaz. Organiza los datos en una estructura de directorios jerárquica en función de los valores diferenciados de una o más columnas.

Por ejemplo, puede decidir particionar los registros de aplicación en Amazon Simple Storage Service (Amazon S3) por fecha, con desglose por año, mes y día. Los archivos que corresponden a los datos de un solo día se colocan con un prefijo como `s3://my_bucket/logs/year=2018/month=01/day=23/`. Los sistemas como Amazon Athena, Amazon Redshift Spectrum, y ahora AWS Glue, pueden utilizar estas particiones para filtrar datos por valor de partición sin tener que leer todos los datos subyacentes desde Amazon S3.

Los rastreadores no solo infieren los tipos de archivo y esquemas, sino que también identifican automáticamente la estructura de particiones del conjunto de datos cuando rellenan AWS Glue Data Catalog. Las columnas de partición resultantes están disponibles para consultarlas en trabajos de ETL de AWS Glue o motores de consulta como Amazon Athena.

Después de rastrear una tabla, puede ver las particiones que creó el rastreador. En la consola de AWS Glue, seleccione **Tables (Tablas)** en el panel de navegación de la izquierda. Elija la tabla creada por el rastreador y, a continuación, elija **View Partitions (Ver Particiones)**.

En el caso de las rutas con particiones de tipo Apache Hive en el estilo `key=val`, los rastreadores rellenan automáticamente el nombre de columna con el nombre de clave. De lo contrario, utiliza nombres predeterminados como `partition_0`, `partition_1` y así sucesivamente. Puede cambiar los nombres predeterminados de la consola. Para ello, navegue hasta la tabla. Compruebe si existen índices en la pestaña **Indexes** (Índices). Si ese es el caso, debe eliminarlos para continuar (puede volver a crearlos con los nuevos nombres de columna más adelante). A continuación, seleccione **Editar esquema** y modifique allí los nombres de las columnas de partición.

En los scripts de ETL, puede filtrar por las columnas de partición. Dado que la información de partición se almacena en el Data Catalog, utilice llamadas a la API `from_catalog` para incluir las columnas de partición en el `DynamicFrame`. Por ejemplo, utilice `create_dynamic_frame.from_catalog` en lugar de `create_dynamic_frame.from_options`.

El particionamiento es una técnica de optimización que reduce el escaneo de datos. Para obtener más información sobre el proceso de identificación de cuándo esta técnica es adecuada, consulte [Reducir la cantidad de datos escaneados](https://docs.aws.amazon.com/prescriptive-guidance/latest/tuning-aws-glue-for-apache-spark/reduce-data-scan.html) en la guía de *Prácticas recomendadas para el ajuste del rendimiento de AWS Glue para trabajos de Apache Spark* en las Recomendaciones de AWS.

## Filtrado previo con predicados de inserción
<a name="aws-glue-programming-etl-partitions-pushdowns"></a>

En muchos casos, puede utilizar un predicado de inserción para filtrar por particiones sin tener que enumerar y leer todos los archivos del conjunto de datos. En lugar de leer todo el conjunto de datos y, a continuación, realizar el filtrado en un objeto DynamicFrame, puede aplicar el filtro directamente en los metadatos de partición en el Data Catalog. A continuación, enumere y lea solo lo que necesita realmente en un objeto DynamicFrame.

Por ejemplo, en Python podría escribir lo siguiente.

```
glue_context.create_dynamic_frame.from_catalog(
    database = "my_S3_data_set",
    table_name = "catalog_data_table",
    push_down_predicate = my_partition_predicate)
```

De este modo se crea un objeto DynamicFrame que solo carga las particiones en el Data Catalog que cumplan la expresión de predicado. En función de lo pequeño que sea un subconjunto de los datos que esté cargando, se puede ahorrar mucho tiempo de procesamiento.

La expresión de predicado puede ser cualquier expresión booleana que admita Spark SQL. Funciona todo lo que podría incluir en una cláusula `WHERE` de una consulta SQL Spark. Por ejemplo, la expresión de predicado `pushDownPredicate = "(year=='2017' and month=='04')"` solo carga las particiones en el Data Catalog que tienen tanto `year` igual que 2017 como `month` igual que 04. Para obtener más información, consulte la [documentación de Apache Spark SQL](https://spark.apache.org/docs/2.1.1/sql-programming-guide.html) y, en concreto, la [referencia de funciones SQL de Scala](https://spark.apache.org/docs/2.1.1/api/scala/index.html#org.apache.spark.sql.functions$).

## Filtrado del lado del servidor mediante predicados de partición de catálogo
<a name="aws-glue-programming-etl-partitions-cat-predicates"></a>

La opción `push_down_predicate` se aplica después de crear el listado de todas las particiones del catálogo y antes de crear el listado de los archivos de Amazon S3 para esas particiones. Si tiene muchas particiones para una tabla, el listado de particiones del catálogo puede seguir incurriendo en sobrecarga de tiempo adicional. Para abordar esta sobrecarga, puede usar la poda de particiones del lado del servidor con la opción `catalogPartitionPredicate` que utiliza [índices de partición](https://docs.aws.amazon.com/glue/latest/dg/partition-indexes.html) en AWS Glue Data Catalog. Esto hace que el filtrado de particiones sea mucho más rápido cuando tiene millones de particiones en una tabla. Puede usar ambos `push_down_predicate` y `catalogPartitionPredicate` en `additional_options` en forma conjunta, si su `catalogPartitionPredicate` requiere sintaxis de predicado que aún no se soporta con los índices de partición del catálogo.

Python:

```
dynamic_frame = glueContext.create_dynamic_frame.from_catalog(
    database=dbname, 
    table_name=tablename,
    transformation_ctx="datasource0",
    push_down_predicate="day>=10 and customer_id like '10%'",
    additional_options={"catalogPartitionPredicate":"year='2021' and month='06'"}
)
```

Scala:

```
val dynamicFrame = glueContext.getCatalogSource(
    database = dbname,
    tableName = tablename, 
    transformationContext = "datasource0",
    pushDownPredicate="day>=10 and customer_id like '10%'",
    additionalOptions = JsonOptions("""{
        "catalogPartitionPredicate": "year='2021' and month='06'"}""")
    ).getDynamicFrame()
```

**nota**  
`push_down_predicate` y `catalogPartitionPredicate` utilizan sintaxis diferentes. El primero utiliza la sintaxis estándar de Spark SQL y el segundo utiliza el analizador JSQL.

## Escritura de particiones
<a name="aws-glue-programming-etl-partitions-writing"></a>

De forma predeterminada, un objeto DynamicFrame no se particiona cuando se escribe. Todos los archivos de salida se escriben en el nivel superior de la ruta de salida especificada. Hasta hace poco tiempo, la única forma de escribir un objeto DynamicFrame en particiones era convertirlo en un objeto DataFrame de Spark SQL antes de la escritura.

Sin embargo, los objetos DynamicFrame ahora admiten la partición nativa mediante una secuencia de claves, utilizando la opción `partitionKeys` al crear un receptor. Por ejemplo, el siguiente código Python escribe un conjunto de datos en Amazon S3 en formato Parquet, en directorios particionados por el tipo de campo. Desde ahí puede procesar estas particiones con otros sistemas, como Amazon Athena.

```
glue_context.write_dynamic_frame.from_options(
    frame = projectedEvents,
    connection_type = "s3",    
    connection_options = {"path": "$outpath", "partitionKeys": ["type"]},
    format = "parquet")
```