Knowledge HubDevelopment

Development Guide

A complete reference for pipeline designers, data engineers, and developers building on or extending DataKnits. Covers the visual canvas, all transformation types, and code generation internals.

Pipeline Canvas

The Canvas is the visual IDE where you design data flows. It is a DAG (Directed Acyclic Graph) editor with a drag-and-drop interface.

Adding a Source Node

  1. Open the Metadata Catalog in the left sidebar.
  2. Expand a connector → schema → table.
  3. Drag the table onto the canvas. A Source Node is created automatically at the drop position, pre-populated with connection details.

Keyboard Shortcuts

ShortcutAction
Ctrl / ⌘ + SSave pipeline draft
Ctrl / ⌘ + ZUndo
Ctrl / ⌘ + Shift + ZRedo
Del / BackspaceDelete selected node
Space + DragPan canvas
Ctrl / ⌘ + ScrollZoom in / out
Ctrl / ⌘ + Shift + VValidate pipeline

Node Types

NodeCategoryDescription
Source NodeI/OReads data from a connected technology. One per data source per pipeline branch.
Target NodeI/OWrites data to a destination. Supports Append, Overwrite, Upsert, Merge write modes.
Filter NodeTransformRemoves rows based on WHERE-clause conditions.
Join NodeTransformInner, Left, Right, Full Outer, Cross, Semi, Anti joins with automatic broadcast hints for small tables.
Aggregate NodeTransformGroup By with Sum, Avg, Count, Min, Max, First, Last, Collect List, Count Distinct, having-clause support.
SCD NodeTransformSlowly Changing Dimension types 1, 2, 3, and 4, plus Surrogate Key generation.
Derive NodeTransformAdds or replaces columns with SQL expressions (withColumn).
Custom SQL NodeTransformArbitrary Spark SQL via createOrReplaceTempView + spark.sql().
Data Quality NodeQualityValidation rules: not_null, range, regex, custom expression. Quarantine or fail on violation.
Repartition NodePerformanceHash, range, or coalesce repartitioning for downstream optimization.
Cache NodePerformanceCache / persist DataFrames at configurable StorageLevels to avoid recomputation.

39 Transformation Components

Every transformation node in the canvas maps 1:1 to a code generator (currently implemented for the PySpark engine). Components are grouped below by category, matching the codegen source layout.

Basic (Row & Column Operations)

ComponentPySpark APINotes
Filterdf.filter(F.expr(...))Include or exclude mode; optional SQL mode for QUALIFY / LATERAL VIEW syntax.
Selectdf.select(F.col(), F.expr().alias())Column projection with expression aliases.
RenamewithColumnRenamed chain
Cast.cast()All standard Spark types; date/timestamp format strings supported.
Drop Columnsdf.drop(...)
DerivewithColumn(F.expr())Add/replace columns; optional target-type cast.
Sortdf.orderBy()Nulls first / last configurable per column.
DeduplicatedropDuplicates() / select().distinct()ALL_COLUMNS or KEY_ONLY output mode.
Fill NAdf.fillna()Per-column dict or single global value.
Drop NAdf.dropna(how, subset)any / all mode, optional column subset.
Limitdf.limit(n)Emits a warning to verify intent in production.
Multi-Transform SequenceChained withColumn() stepsColumn-level pipeline of micro-transformations — see Column Function Library below.

Advanced

ComponentPySpark APINotes
Joininner / left / right / full / cross / left_semi / left_antiPython-level broadcast hint or SQL hint mode (BROADCAST / SHUFFLE_HASH / SHUFFLE_MERGE / SKEW).
Unionunion() / unionByName()Also supports INTERSECT / EXCEPT via SQL temp views.
AggregategroupBy().agg(), rollup(), cube(), GROUPING SETScount, sum, avg, min, max, first, last, collect_list, collect_set, countDistinct, approx_count_distinct, percentile_approx; optional HAVING clause.
WindowWindow.partitionBy().orderBy()row_number, rank, dense_rank, percent_rank, cume_dist, lag, lead, ntile, sum, avg, min, max, count, first, last; per-function frame overrides (rowsBetween / rangeBetween).

Utility

ComponentPySpark APINotes
Sampledf.sample(withReplacement, fraction, seed)
LookupBroadcast join against a reference datasetSelects only needed lookup columns; optional cache; fills defaults for unmatched rows.
Custom UDFPython, SQL, Pandas UDF, or Scala5 Pandas UDF variants: series_to_series, iterator_series, series_to_scalar, map_in_pandas, apply_in_pandas.
Add Audit ColumnswithColumn()Injects _load_ts, _run_id, _run_user (configurable names).
Case WhenF.when().when().otherwise()Single output column, ordered condition list.
Broadcast VariablesparkContext.broadcast()Optional UDF-based lookup columns generated from the broadcast dict.
AccumulatorsparkContext.accumulator()Driver-side counter across executors; int or float.

Special

ComponentPySpark APINotes
PivotgroupBy().pivot().agg()Optional explicit pivot value list.
UnpivotF.expr("stack(...)")
ExplodeF.explode() / F.explode_outer()
FlattenInline _flatten_df() helperFlattens nested struct columns; configurable separator and column subset.
Custom SQLcreateOrReplaceTempView + spark.sql()Multi-input support via {input} / {input1} placeholders.
Data QualityFilter/count-based rule checksnot_null, range, regex, unique, custom rules; fail, drop, quarantine, or warn-only.
Repartitionrepartition() / repartitionByRange() / coalesce()Hash, range, or coalesce strategy.
Cachedf.cache() / df.persist(StorageLevel.X)Optional eager materialization via .count().
Iceberg DMLspark.sql("DELETE/UPDATE/MERGE INTO ...")Row-level DML on Iceberg tables. WHERE clause mandatory for DELETE/UPDATE. Pass-through node — does not modify the upstream DataFrame.
Data Profiledescribe(), null counts, approx_count_distinct()Read-only, pass-through — logs profile stats without modifying data.
Maskhash / null / truncate / replace / regex_replacePII masking; hash uses F.sha2(..., 256).

SCD & Keys

ComponentPySpark APINotes
SCD Type 1Delta MERGE INTOOverwrites matched records, inserts new ones. No history.
SCD Type 2Hash-based change detection + Delta/Iceberg MERGECloses changed records, inserts new versions. Optional soft-delete handling closes rows absent from source.
SCD Type 3Join + column shiftMaintains prev_{column} alongside current value for tracked columns.
SCD Type 4Hash-based change detection + separate history table writeMain table keeps current row only; changed rows are appended to a dedicated history table (Delta or Iceberg).
Surrogate Keymonotonically_increasing_id() / uuid() / row_number()row_number strategy requires orderBy for deterministic keys.

Column Function Library (Multi-Transform Sequence)

The Multi-Transform Sequence component chains column-level micro-transformations, each compiled to a PySpark column expression. The library covers 169 functions across 14 categories. Each category links to a dedicated reference page with full syntax, parameters, and defaults for every function.

CategoryCountDescription
Convert3Type coercion between numbers, dates, and target types.
String25Trimming, casing, padding, substring, and character-level operations.
Date / Time44Date arithmetic, part extraction, formatting, and timezone handling.
Regex5Pattern extraction, replacement, and matching.
Conditional / Null Handling7Null coalescing, CASE WHEN logic, and list membership checks.
Arithmetic4Add, subtract, multiply, divide against a second operand.
Numeric42Rounding, trigonometry, logarithms, random numbers, and bitwise ops.
Type / Encoding5Hex/binary/base conversions, safe casting, and custom SQL expressions.
String Extras / Hashing16Splitting, formatting, hashing (SHA1/MD5), and URL/Base64 encoding.
Crypto2AES encryption and decryption.
JSON2Extracting values from and parsing JSON strings.
Array7Array containment, sizing, sorting, and joining.
Struct / Map3Reading struct fields and map keys/values.
Boolean Aggregates4every, some, count_if, any_value.

Each step supports an onError policy (RETURN_NULL or USE_DEFAULT with a configured default value), and steps within a sequence chain on the output of the previous step.

Slowly Changing Dimensions (SCD)

The SCD node handles historical tracking for dimension tables without writing custom merge logic. See the SCD & Keys table above for the full list of implemented types (1, 2, 3, 4) and the Surrogate Key generator.

TypeStrategyColumns Added / Written
SCD Type 1Overwrite old values with new values. No history retained.None
SCD Type 2Insert new row for changes. Marks old row as inactive. Full historical tracking. Optional soft-delete handling closes rows absent from source.end_date, is_current-style flag column (configurable names)
SCD Type 3Partial history. Stores current and previous values in separate columns.prev_{col} for each tracked column
SCD Type 4Main table keeps only the current row; changed rows are written to a separate history table.effective_date column on history table rows

Pushdown Eligibility System

DataKnits automatically analyzes each pipeline segment and surfaces a real-time eligibility indicator. You can toggle execution points between Source DB and PySpark from the canvas.

Eligibility Rules

Function Availability Badges

BadgeMeaning
✓ AvailableWorks natively in the source database.
⚠ AlternativeWorks with different syntax (e.g., CASE WHEN instead of IF() in Oracle). DataKnits generates the correct dialect automatically.
✗ UnavailableRequires PySpark. Canvas offers a one-click switch to PySpark execution for that segment.

Execution & Monitoring

After clicking Run, the Execution Monitor shows real-time progress of your pipeline:

Re-running Failed Jobs

Operators can re-run any failed job within the last 30 days from the execution history. The original pipeline version and environment config are used — changes to the pipeline draft do not affect the re-run.