- Newest
- Most votes
- Most comments
I understand that you have a requirement that you need to dynamically alter the partitions for each write so that it matches the directory structure of your source data. I suggest a method for allowing to pass the directory structure of the source data to your write job by including the directory structure as metadata columns in your json object, as well as some potential issues that will occurs with changing partitions in your destination.
You can effectively write the 'year', 'month', 'day' and 'hr' format using ‘partitionKeys’ in your connection options. [1][2] “partitionKeys” is an optional key in the connection_options parameter in the write_dynamic_frame.from_options() function, which allows you to create partitions as S3 folders (directories) on write.
It's generally not advisable to change your partitioning structure frequently, as predicate pushdown and tools leveraging partitions for query optimization require consistent partition formats to function efficiently. Changing the structure could impact query performance and break compatibility with existing processes.
However if your use case requires creating unique file structures for each of your write operations, one could still leverage the partitionKeys to achieve this dynamic creation of unique folder structures for each write so it always matches the existing directory structure of the source data. For example in your script prior to write your code could check for the existence of columns you use for partitioning, and add the list of the existing columns in your actual data that are in that list passing it to the partitionKeys value. In this way you would allow for ‘passing’ the available partitions to the write operation by excluding certain columns to be used for partitions from the source file. Your json objects being flattened would just need to have those partition columns updated when publish to s3 for ingestion by your Spark job.
Some example sudo code illustrating the method above:
available_partition_columns = [col for col in ["year", "month", "day", "hour"] if col in dynamic_frame.toDF().columns]
glue_context.write_dynamic_frame.from_options(
frame = dynamic_frame,
connection_type = "s3",
connection_options = {…, "partitionKeys": available_partition_columns, …},
format = "parquet")
This approach allows for flexibility in your partition structure so that it will change on each write based on the columns you pass it to create partition folders by. However, be cautious with this method, as it may lead to inconsistent partitioning across your dataset, potentially complicating queries and integrating with upstream tools which otherwise would be able to limit the data you need to query leveraging partitions. Many tools that query S3 charge by the amount of data scanned which you can limit leveraging partitions, such as Athena: https://calculator.aws/#/createCalculator/Athena
References
answered 2 years ago
Relevant content
- AWS OFFICIALUpdated 2 years ago
- AWS OFFICIALUpdated 2 years ago
