ꘇ dat.merge
Stack two tables, and know that it's stacking, not joining
- input
- other
- table
- text
What it is
ꘇ dat.merge takes two tables and gives you back one table. Two inputs, input and other, both GENERETI_DAT; two outputs, the usual table and text.
That's the whole node, and the whole point is to be unambiguous about what kind of merge it is, because "merge" means at least three different things to three different people. This is row concatenation: the rows of other are appended after the rows of input. It is not a join on a key. It is not a column-wise combine. There is no dedupe, no field matching, and no header reconciliation.
In practice, that's exactly what you want most of the time. You've got a parameter table and a second parameter table, you want them to be one parameter table. Done.
What the absence of header logic means
This is the part that bites, and it's worth being concrete about it. If both tables carry a header row - say name,value on each - you get a merged table where the header appears twice: once at the top, and once somewhere in the middle where the second table's header landed. Because the header is just a row as far as the table type is concerned, nothing strips it.
Usually that's harmless: dat.tochop reads row one as channel names and treats everything after as samples, so the stray header row becomes one sample whose non-numeric cells convert to 0.0. You get a blip at that position in every channel. Not fatal, occasionally confusing, and the fix is to either strip the second header with dat.select (start of 1, count of whatever) or just not have one.
If the two tables have different column counts, that's also fine - the merged table is simply ragged. Downstream nodes handle it in their own ways: dat.select fills out-of-range columns with empty strings, dat.transpose pads short rows with empty strings.
Why you'd reach for it
The clean use case in this pack is parameter accumulation. Build a couple of small tables from different sources - one pasted as CSV in dat.table, one parsed out of JSON by dat.json - merge them into a single parameter table, then run the result through dat.select to pick and order the columns you actually want before dat.tochop turns them into named channels.
The other use case is trimming: merge is cheap, so people use it as "append a literal row of overrides to whatever came in", which is a slightly abusive but perfectly effective way to pin a value regardless of upstream input.
There's a sibling worth knowing about: chop.merge does the same job for sampled channels, with one important difference - it resamples the second signal onto the first's timeline with linear interpolation, so channel lengths don't have to match. dat.merge has no such courtesy; rows are rows.
Inputs, outputs, wiring
input-GENERETI_DAT, the base.other-GENERETI_DAT, appended after it.table- the concatenatedGENERETI_DAT.text- the concatenated CSV.
Both inputs are required, so an unconnected other stops the graph rather than silently passing through. That's the right call for a node whose entire job is combining two things, but it does mean you can't leave it half-wired "just in case".
Install
Part of the Genereti pack; there's no separate distribution. Manager → search Genereti (publisher liuboto) → install → restart → refresh the browser page. Manual:
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
Swap in your own interpreter if you're not on a .venv checkout - Windows Portable is python_embeded\python.exe, Comfy Desktop has its own. The requirements file is one line, comfyui-frontend-package>=1.53.6; no models, no extra packs, no compiled dependencies. Target versions are ComfyUI 0.38.2+, Python 3.11+, frontend 1.53.6+.
Gotchas
- Two headers in, two headers out. Nothing strips them.
- Order matters and there's no sort.
inputfirst, always. If you need deterministic ordering across sources, do it after the merge. - Ragged tables are allowed and therefore likely. Check
textoutput throughdat.inspectbefore you trust the shape. - Alpha pack. The README's framing - "super alpha - early classroom testing… expect bugs and changing interfaces" - applies. Node IDs are stable, so workflows survive updates; behaviour may still be adjusted.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| input | GENERETI_DAT | — | |
| other | GENERETI_DAT | — |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| table | GENERETI_DAT | — |
| text | STRING | — |