AWS Glue Studio is a graphical interface that makes it easy to create, run, and monitor extract, transform, and load (ETL) jobs in AWS Glue. It allows you to visually compose data transformation workflows using nodes that represent different data handling steps, which later are converted automatically into code to run.
AWS Glue Studio recently released 10 more visual transforms to allow creating more advanced jobs in a visual way without coding skills. In this post, we discuss potential uses cases that reflect common ETL needs.
The new transforms that will be demonstrated in this post are: Concatenate, Split String, Array To Columns, Add Current Timestamp, Pivot Rows To Columns, Unpivot Columns To Rows, Lookup, Explode Array Or Map Into Columns, Derived Column, and Autobalance Processing.
In this use case, we have some JSON files with stock option operations. We want to make some transformations before storing the data to make it easier to analyze, and we also want to produce a separate dataset summary.
In this dataset, each row represents a trade of option contracts. Options are financial instruments that provide the right—but not the obligation—to buy or sell stock shares at a fixed price (called strike price) before a defined expiration date.
The data follows the following schema:
The following is a sample of the synthetic data generated for this post:
This data has a number of unique characteristics, as often found on older systems, that make the data harder to use.
The following are the ETL requirements:
bought and sold are mutually exclusive; we can consolidate them into a single column with the contract numbers and have another column indicating if the contracts where bought or sold in this order.Based on those requirements, the job will produce two outputs:

You will need your own S3 bucket to follow along with this use case. To create a new bucket, refer to Creating a bucket.
To follow along with this post (or experiment with this kind of data on your own), you can generate this dataset synthetically. The following Python script can be run on a Python environment with Boto3 installed and access to Amazon Simple Storage Service (Amazon S3).
To generate the data, complete the following steps:
--bucket and assign as the value the name of the bucket you want to use to store the sample data.Each run will generate a JSON file with 1,000 rows under the bucket specified and prefix transformsblog/inputdata/. You can run the job multiple times if you want to test with more input files.
Each line in the synthetic data is a data row representing a JSON object like the following:
To create the AWS Glue visual job, complete the following steps:
Untitled job to give it a name and assign a role suitable for AWS Glue on the Job details tab.JSON files source) and enter the S3 URL under which the files are stored (for example, s3://<your bucket name>/transformsblog/inputdata/), then select JSON as the data format.From this source node, you’ll keep chaining transforms. When adding each transform, make sure the selected node is the last one added so it gets assigned as the parent, unless indicated otherwise in the instructions.
If you didn’t select the right parent, you can always edit the parent by selecting it and choosing another parent in the configuration pane.

For each node added, you’ll give it a specific name (so the node purpose shows in the graph) and configuration on the Transform tab.
Every time a transform changes the schema (for instance, add a new column), the output schema needs to be updated so it’s visible to the downstream transforms. You can manually edit the output schema, but it’s more practical and safer to do it using the data preview.
Additionally, that way you can verify the transformation are working so far as expected. To do so, open the Data preview tab with the transform selected and start a preview session. After you have verified the transformed data looks as expected, go to the Output schema tab and choose Use data preview schema to update the schema automatically.
As you add new kinds of transforms, the preview might show a message about a missing dependency. When this happens, choose End Session and the start a new one, so the preview picks up the new kind of node.
Let’s start by dealing with the information on the instrument name to normalize it into columns that are easier to access in the resulting output table.
Split instrument, which will tokenize the instrument column using a whitespace regex: \s+ (a single space would do in this case, but this way is more flexible and visually clearer).instrument\_arr.
Instrument columns to convert the array column just created into new fields, except for symbol, for which we already have a column.instrument\_arr, skip the first token and tell it to extract the output columns month, day, year, strike\_price, type using indexes 2, 3, 4, 5, 6 (the spaces after the commas are for readability, they don’t impact the configuration).
The year extracted is expressed with two digits only; let’s put a stopgap to assume it’s in this century if they just use two digits.
Four digits year.year as the derived column so it overrides it, and enter the following SQL expression:CASE WHEN length(year) = 2 THEN ('20' || year) ELSE year END
For convenience, we build an expiration\_date field that a user can have as reference of the last date the option can be exercised.
Build expiration date.expiration\_date, select the columns year, month, and day (in that order), and a hyphen as spacer.
The diagram so far should look like the following example.

The data preview of the new columns so far should look like the following screenshot.

Each of the rows in the data indicates the number of contracts of each option that were bought or sold and the batches on which the orders were filled. Without losing the information about the individual batches, we want to have each amount on an individual row with a single amount value, while the rest of the information is replicated in each row produced.
First, let’s merge the amounts into a single column.
Unpivot actions.bought and sold to unpivot and store the names and values in columns named action and contracts, respectively.
contracts is still an array of numbers after this transformation.Explode contracts.contracts column and enter contracts as the new column to override it (we don’t need to keep the original array).The preview now shows that each row has a single contracts amount, and the rest of the fields are the same.
This also means that order\_id is no longer a unique key. For your own use cases, you need to decide how to model your data and if you want to denormalize or not.

The following screenshot is an example of what the new columns look like after the transformations so far.

Now you create a summary table with the number of contracts traded for each type and each stock symbol.
Let’s assume for illustration purposes that the files processed belong to a single day, so this summary gives the business users information about what the market interest and sentiment are that day.
symbol, type, and contracts.
Pivot summary.contracts column using sum and choose to convert the type column.
Normally, you would store it on some external database or file for reference; in this example, we save it as a CSV file on Amazon S3.
Single output file.1 in the number of partitions configuration.
CSV Contract summary.The last part of the job should now look like the following example.


In preparation for saving the orders into a historical table for future analysis, let’s clean up some temporary columns created along the way.
Explode contracts node selected as its parent (we are branching the data pipeline to generate a separate output).instrument\_arr, month, day, and year.
This synthetic data contains fictional operations on two currencies, but in a real system you could get currencies from markets all over the world. It’s useful to standardize the currencies handled into a single reference currency so they can be easily be compared and aggregated for reporting and analysis.
We use Amazon Athena to simulate a table with approximate currency conversions that gets updated periodically (here we assume we process the orders timely enough that the conversion is a reasonable representative for comparison purposes).
default (if you do that, update the table qualified name accordingly in the examples provided). INSERT INTO default.exchange\_rates VALUES ('usd', 1.0), ('eur', 1.09), ('gbp', 1.24);SELECT * FROM default.exchange\_rates
Drop Fields) and name it Exchange rate.currency as the key and select the exchange\_rate field to use.currency and don’t need to define a mapping.
Total in usd.total\_usd and use the following SQL expression:round(contracts * price * exchange\_rate, 2)
ingest\_date.%Y-%m-%d for your timestamp (for demonstration purposes, we are just using the date; you can make it more precise if you want to).
To save the historical orders table, complete the following steps:
Orders table.option\_orders.
The last part of the diagram should now look similar to the following, with two branches for the two separate outputs.

After you run the job successfully, you can use a tool like Athena to review the data the job has produced by querying the new table. You can find the table on the Athena list and choose Preview table or just run a SELECT query (updating the table name to the name and catalog you used):
SELECT * FROM default.option\_orders limit 10
Your table content should look similar to the following screenshot.

If you don’t want to keep this example, delete the two jobs you created, the two tables in Athena, and the S3 paths where the input and output files were stored.
In this post, we showed how the new transforms in AWS Glue Studio can help you do more advanced transformation with minimum configuration. This means you can implement more ETL uses cases without having to write and maintain any code. The new transforms are already available on AWS Glue Studio, so you can use the new transforms today in your visual jobs.
Gonzalo Herreros is a Senior Big Data Architect on the AWS Glue team.