All community nodes
Unpack icon

Unpack

v0.1.0

Flattens one nested column: a List of scalars explodes into one row per element, a Struct unnests into one column per field, and a List of Structs explodes and then unnests into one row per element with one column per field. Empty lists and nulls follow Polars' default explode semantics and yield a

Utilities Runs locally No flagged operations
Unpack screenshot 1 Unpack screenshot 2

Unpack

Flatten one nested column into plain rows and columns. Point it at a List, a Struct, or a List(Struct) column and it picks the right operation:

Column typeWhat happensRowsColumns
List of scalarsExplode — one row per elementmultiplyunchanged
StructUnnest — one column per fieldunchangedadd
List(Struct)Explode, then unnest — one row per element, one column per fieldmultiplyadd

Typical sources of nested columns are JSON files, REST API responses, and Delta or Parquet tables written by other systems. Unpack turns those into a flat table you can filter, join, and aggregate.

Inputs

PortDescription
input[0]A table containing at least one nested (List or Struct) column.

Settings

SettingTypeDefaultDescription
Column to unpackcolumn (complex)—The List, Struct, or List(Struct) column to flatten. (required)
Prefix unnested fields with column nametoggleonName new columns <column>_<field> instead of just <field>, so unpacking several columns never collides.
Keep original columntoggleoffKeep the nested column next to the unpacked fields instead of replacing it.
Explode only (skip unnest for List(Struct))toggleoffFor List(Struct), stop after the explode and leave one Struct per row. Useful when you want to unpack the struct in a later step, or only some of its fields.

Output

The same table with the nested column replaced by (or, with Keep original column, followed by) its flattened contents. Unpacked columns land in the position of the source column, so the column order stays predictable. All other columns are untouched; on an explode their values are repeated for every emitted row.

Example

Bike-share station feed, one row per station, with a List(Struct) of vehicle counts:

station_idnum_docks_availablevehicle_types_available
a10[{"vehicle_type_id": "1", "count": 3}, {"vehicle_type_id": "2", "count": 1}]
b4[{"vehicle_type_id": "1", "count": 0}, {"vehicle_type_id": "2", "count": 2}]

Unpack vehicle_types_available with the defaults (prefix on, keep original off):

station_idnum_docks_availablevehicle_types_available_vehicle_type_idvehicle_types_available_count
a1013
a1021
b410
b422

With Prefix off and Keep original column on, the struct stays and the fields keep their short names:

station_idnum_docks_availablevehicle_types_availablevehicle_type_idcount
a10{"1", 3}13
a10{"2", 1}21
b4{"1", 0}10
b4{"2", 2}22

A plain Struct column such as address = {"city": "Utrecht", "zip": "3511"} becomes two columns, address_city and address_zip, with no change in row count. A plain List column such as tags = ["a", "b"] becomes two rows with tags = "a" and tags = "b".

Notes and edge cases

  • Empty lists and nulls follow Polars’ explode semantics: they produce one row with a null rather than dropping the row. Add a Filter node afterwards if you want them gone.
  • Name collisions are an error, not a silent overwrite. If an unpacked field would shadow an existing column, the node stops and tells you which names collide and which toggle to flip. Turning Prefix on resolves nearly every case.
  • Deeper nesting is unpacked one level per node. For List(Struct) whose fields are themselves structs or lists, chain a second Unpack on the field you need.
  • Non-nested columns are rejected with a clear error; the column selector only offers complex types to begin with.
  • Runs locally in the worker on a lazy Polars frame. No kernel or Docker required, and nothing is materialised until downstream asks for it.

Metadata

  • Category: Transform
  • Version: 0.1.0
  • Tags: explode, unnest, list, struct, json, flatten