Etlworks Scripting
JavaScript (default) and Python inside every Etlworks flow. Field functions in Mapping, dataset transformations, conditions, loops, validation, custom logic flows — with direct access to the Etlworks Java API and core JVM classes.
JavaScript first
Powered by Nashorn — the JavaScript engine embedded in the JVM. Full standard JS plus seamless access to every Java class. Recommended for nearly everything.
Python (Jython 2.7)
For lightweight inline logic. Imports Java classes too. Note: no pip, no Python 3, no pandas — for those, use the Execute Script Local or Remote via SSH flow.
Everywhere you need it
Mapping field functions, scripting transformations (Before / For Each Row / After), validation, conditions, loops, exception handlers, dynamic SQL, the dedicated Script flow.
Direct Java & Etlworks APIs
Import any class with Java.type("...") or importPackage(). FileManagerTask, Extractor, SqlUtils, ConnectorUtils, jsoup for HTML — all one line away.
Runtime objects on tap
etlConfig, scenario, dataSet, currentRow, row — injected by name into your script. scenario.getVariable("…").getValue() for flow vars; etlConfig.setValue() for typed key/value storage.
25+ recipes
Lookups, anonymization, validation, conditional SQL, web scraping, JSON/XML serialization, sequence generators, sharing parameters across flows, working with dates — copy/paste-ready.
See it in action
Three real shapes from production: a calculated mapping field, an anonymizer, and a validator.
// Concatenate first + last name; fall back to email if either is missing.
var first = dataSet.getFieldValue(currentRow, 'first_name');
var last = dataSet.getFieldValue(currentRow, 'last_name');
var email = dataSet.getFieldValue(currentRow, 'email');
value = (first && last) ? (first + ' ' + last) : (email || '');
// Generate an anonymous email but always return the SAME anonymous value
// for the same source value (within this flow).
var randomizer = etlConfig.randomizer("en");
randomizer.reuse(fieldValue, randomizer.internet().emailAddress());
// Reject the current row if postal_code or phone is empty / non-numeric.
var postalCode = dataSet.getFieldValue(currentRow, 'postal_code');
var phone = dataSet.getFieldValue(currentRow, 'phone');
if (Utils.isNothing(postalCode) || Utils.isNothing(phone) || !Utils.isNumber(postalCode)) {
value = TaskResult.REJECT;
} else {
value = TaskResult.CONTINUE;
}