Nodes/ꘇ Genereti/ꘇ dat.select
ComfyUI Node

ꘇ dat.select

The row-and-column slice that makes tables useful

By languel·Created about a month ago·Updated 3 days ago· 1
ꘇ dat.select
  • input
  • table
  • text
◄start0►
◄count100000►
◄columns►

What it does

ꘇ dat.select is the DAT family's cropping tool: give it a table, tell it which rows and which columns you want, get a smaller table back. It's the node that turns "a CSV I pasted" into "the two numbers I need", which is most of what anyone ever wants from tabular data in a graph.

If you've used top.crop on textures, this is the same idea applied to text. Genereti's whole OpenTouch layer is built on that symmetry - TOP for images, CHOP for sampled channels, DAT for tables and documents - and each family gets the same primitive operations. Selection, merge, transpose, replace: they exist in all three.

The three knobs

  • start - first row, zero-based, default 0. Clamped at zero internally, so a negative value just means row 0.
  • count - how many rows to take, default 100000, i.e. "all of them". This default is the reason dat.select is safe to drop into a chain purely for its column filter: leave start/count alone and you pass the row count through untouched.
  • columns - a space-separated list of zero-based column indices, default empty, which means "keep all columns". 0 2 3 keeps the first, third and fourth columns in that order.

That last detail is the trap. columns is split on whitespace, so it's 0 2 3, not 0,2,3 - and this is not the same convention as dat.json's selection field, which is comma-separated. Two nodes in the same category, two different separators. If your select comes back as garbage, check for commas first.

Reordering is a genuine feature, by the way: 3 0 gives you the fourth column then the first, which is handy for making a header row come out in the order dat.tochop will read it.

The mechanism, and where it's forgiving

The implementation builds a fresh table from the intersection you asked for. Where a requested column doesn't exist in that row - ragged data, short rows, a typo'd index - you get an empty string in that cell rather than an error. Same for rows past the end: you just get fewer rows.

That forgiving behaviour cuts both ways. It means you can't break the node with a bad index, and it also means a typo produces a silently empty column instead of a complaint. If a channel downstream is flat zero, the sequence to check is: did dat.select actually keep that column?

One thing it isn't: there's no filter-by-value here. This node does positional selection only. dat.json's filter field is the closest thing the pack has to a search, and it lives on the JSON node.

Inputs and outputs

Inputs are input (GENERETI_DAT), plus start, count, columns as above. Outputs are the DAT twins: table (GENERETI_DAT) and text (STRING, the CSV re-serialised from the sliced rows - so the text output shows the selection, which makes it a decent thing to wire into dat.inspect while you're setting indices).

And that's a workflow worth naming explicitly: put dat.inspect on the text output of dat.select. Inspect bounds the output at 32 items by default and pretty-prints it, so you can iterate on start/count/columns and watch the selection change without leaving the graph. Debugging tabular data in ComfyUI is genuinely painful without it.

Downstream, a selected table usually becomes either channels (dat.tochop, columns as named channels, rows as samples) or an image (dat.totop, cells as pixels). Or nothing at all - dat.select is also legitimately used to build a document to display, since the DAT nodes share the pack's document export for Markdown/HTML.

Install

Comes with the Genereti pack. ComfyUI Manager → search Genereti (publisher liuboto) → install → restart → hard-refresh the browser. Manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/languel/genereti.git genereti
cd ../
./.venv/bin/python -m pip install -r custom_nodes/genereti/requirements.txt

Use the Python that belongs to your install (python_embeded\python.exe for Windows Portable). Requirements are a single line - comfyui-frontend-package>=1.53.6 - so nothing model-sized gets pulled. Needs ComfyUI 0.38.2+, Python 3.11+; the reference build is macOS/Apple Silicon, and the README is upfront that Windows/Linux classrooms haven't been verified as heavily.

Gotchas

  • Space-separated columns. Say it twice.
  • Empty output ≠ empty input. Missing indices become empty strings, which dat.tochop then converts to 0.0. A dead channel is usually a wrong index, not a wrong table.
  • It copies. Everything here is an immutable string table, so each operator produces a new one. Fine at classroom sizes; don't build a 100k-row pipeline and then wonder why Queue feels sticky.
  • The pack is "super alpha" per its own README, with an explicit "back up your workflows before updating." This node's behaviour is simple enough that it's unlikely to churn; the pack around it will.
CategoryGenereti / DAT

Inputs (4)

NameTypeDefaultDescription
inputGENERETI_DAT—
startINT00–100000—
countINT1000000–100000—
columnsSTRING—

Outputs (2)

NameTypeDescription
tableGENERETI_DAT—
textSTRING—