Nodes/Nova Audio Player/Nova SQLite Row Iterator & Splitter ๐Ÿ“ฆ
ComfyUI Node

Nova SQLite Row Iterator & Splitter ๐Ÿ“ฆ

Queue the Whole Table and Walk Away

By NovaFemmeยทCreated 2 months agoยทUpdated 12 days agoยท 1
Nova SQLite Row Iterator & Splitter ๐Ÿ“ฆ
  • row_data_json
  • next_row_index
  • total_rows
  • loop_finished
  • col_0
  • col_1
  • col_2
  • col_3
  • col_4
  • col_5
  • col_6
  • col_7
  • col_8
  • col_9
  • col_10
  • col_11
  • col_12
  • col_13
  • col_14
  • col_15
  • col_16
  • col_17
  • col_18
  • col_19
  • col_20
  • col_21
  • col_22
  • col_23
  • col_24
  • col_25
  • col_26
  • col_27
  • col_28
  • col_29
  • col_30
  • col_31
  • col_32
  • col_33
  • col_34
  • col_35
  • col_36
  • col_37
  • col_38
  • col_39
  • col_40
  • col_41
  • col_42
  • col_43
  • col_44
  • col_45
  • col_46
  • col_47
  • col_48
  • col_49
  • col_50
  • col_51
  • col_52
  • col_53
  • col_54
  • col_55
  • col_56
  • col_57
  • col_58
  • col_59
  • col_60
  • col_61
  • col_62
  • col_63
โ—„row_index0โ–บ
โ—„stop_at_row-1โ–บ
โ—„loop_modeincrementโ–บ
โ—„auto_looptrueโ–บ

Everyone who asks "how do I generate hundreds of renders overnight from a list" gets told the same thing: an INT node that increments, wired into a PromptLine or a text node. It works - and it's also the flakiest part of most people's graphs, because the increment lives in a widget and nothing tells you which row you're on until you read the console.

Nova SQLite Row Iterator & Splitter ๐Ÿ“ฆ is the same idea with the bookkeeping done for you. It takes a table's rows, emits one row's columns as real outputs, and then - if you let it - re-queues the prompt itself until the table runs out.

What it actually does

Wire row_data_json from Nova Dynamic SQLite Browser ๐Ÿ“ into it and the node shows the current row on its own canvas, with col_0, col_1, โ€ฆ outputs that are named after your actual columns. Column one is your filename, column two is your prompt, column five is your BPM - wire each where it belongs and the table drives the whole render.

Mechanically, the split of labour is worth knowing because it explains every behaviour you'll notice. The Python side is stateless: it reads row_index, picks that row out of the JSON, converts each value to a string, and returns next_row_index, total_rows, loop_finished and the column values, plus a UI payload the node uses to redraw its row view. The looping is client-side. The node's JS onExecuted handler, when the loop isn't finished and auto_loop is on, writes next_row_index back into the row_index widget and calls app.queuePrompt(0, 1) fifty milliseconds later. That's it. One queue entry per row, driven from the browser tab.

Which means: the loop stops when you hit Cancel (execution-interrupt and error events both clear it), and it keeps going while the tab is open - close the tab mid-run and the loop ends with the current row.

The inputs that matter

Five inputs, and the defaults are already right for a straight first-to-last run:

  • row_data_json - force-input from the browser. Nothing else produces this type.
  • row_index - 0-based, where to start. Set it to 0 and forget it.
  • stop_at_row - -1 means last row in increment mode, first row in decrement mode. Change it when you want to render rows 6 through 9 while you tune something.
  • loop_mode - increment, decrement, or fixed. fixed is the quiet useful one: it emits exactly the row you selected and immediately reports finished, which is how you preview one row without running the loop.
  • auto_loop - on by default. On means hands-off; off means it advances the widget to the next row and waits for you to click Run again. If you don't trust a table yet, run with it off for two rows first. That's the habit I'd build.

Outputs: next_row_index, total_rows, loop_finished (the three fixed slots - wire loop_finished into anything you want gated on the last row), then the column slots.

Install

ComfyUI Manager, search ComfyUI-NovaAudioPlayer, or by hand:

cd ComfyUI/custom_nodes
git clone https://github.com/NovaFemme/ComfyUI-NovaAudioPlayer.git

Restart, and the node is under โ–ถ๏ธ Nova Audio โ†’ ๐Ÿ“ฆ Delivery & Metadata. These SQLite nodes need no extra packages - sqlite3 ships with Python. The pack's declared mutagen/pymysql dependencies belong to its tag and MySQL nodes and are imported lazily, so a plain clone is fine. The quickest way to see the iterator working is to copy the example database into your input folder and load the pack's own workflow:

cp ComfyUI/custom_nodes/ComfyUI-NovaAudioPlayer/examples/nova_album_example.db ComfyUI/input/album_data.db

Where people get burned

Nothing wired and no columns ticked. The iterator reports "0 columns selected: select at least one column badge on the SQLite Browser" and stops. The selection lives on the browser, not here - this node mirrors whatever it gets.

stop_at_row before row_index in increment mode is a hard error, not a clamp, and that's the author being helpful: a silently zero-row run wastes your time.

The output slots move. The iterator builds its sockets from the browser's ticked columns, so re-ticking columns re-creates the outputs, and links are restored by column name where the name still exists. Change your column selection on a wired-up graph and you should glance at the wires before you queue.

Widget values after a reload. ComfyUI restores widget values by position, which can shift row_index and stop_at_row by a slot. The pack defends against this by also saving those values by name in node properties and restoring them on load - but the lesson still stands: don't save and reload a workflow halfway through a loop and assume the iterator remembers where it was. It remembers its starting row, not its progress.

Row order. The browser's query has no ORDER BY, so "increment" means SQLite's natural order, which for a normal table is insert order and nothing stronger. If your pipeline depends on a specific sequence, add an explicit sort column to the table and read it in that order rather than trusting the file.

One last thing worth internalizing: this node is an output node, so it executes even with nothing wired downstream - that's how the row view updates. It also means a graph with auto_loop left on will keep queueing after you've wandered off. Table of six rows, great. Table of six thousand, you'll want to know where Cancel is.

Categoryโ–ถ๏ธ Nova Audio/๐Ÿ“ฆ Delivery & Metadata

Inputs (5)

NameTypeDefaultDescription
row_data_jsonNOVA_SQLITE_ROWSRows from Nova Dynamic SQLite Browser or Nova SQLite Data Table & Filter.
row_indexINT00โ€“999999The row this run outputs (0-based). With auto_loop on it moves by one after each run.
stop_at_rowINT-1-1โ€“999999-1 = last row (increment) / first row (decrement)
loop_modeCOMBOincrementincrement: step forward one row per run. decrement: step back one row per run. fixed: stay on row_index.
auto_loopBOOLEANtrueAutomatically queue the next row until the loop finishes

Outputs (67)

NameTypeDescription
next_row_indexINTโ€”
total_rowsINTโ€”
loop_finishedBOOLEANโ€”
col_0STRINGโ€”
col_1STRINGโ€”
col_2STRINGโ€”
col_3STRINGโ€”
col_4STRINGโ€”
col_5STRINGโ€”
col_6STRINGโ€”
col_7STRINGโ€”
col_8STRINGโ€”
col_9STRINGโ€”
col_10STRINGโ€”
col_11STRINGโ€”
col_12STRINGโ€”
col_13STRINGโ€”
col_14STRINGโ€”
col_15STRINGโ€”
col_16STRINGโ€”
col_17STRINGโ€”
col_18STRINGโ€”
col_19STRINGโ€”
col_20STRINGโ€”
col_21STRINGโ€”
col_22STRINGโ€”
col_23STRINGโ€”
col_24STRINGโ€”
col_25STRINGโ€”
col_26STRINGโ€”
col_27STRINGโ€”
col_28STRINGโ€”
col_29STRINGโ€”
col_30STRINGโ€”
col_31STRINGโ€”
col_32STRINGโ€”
col_33STRINGโ€”
col_34STRINGโ€”
col_35STRINGโ€”
col_36STRINGโ€”
col_37STRINGโ€”
col_38STRINGโ€”
col_39STRINGโ€”
col_40STRINGโ€”
col_41STRINGโ€”
col_42STRINGโ€”
col_43STRINGโ€”
col_44STRINGโ€”
col_45STRINGโ€”
col_46STRINGโ€”
col_47STRINGโ€”
col_48STRINGโ€”
col_49STRINGโ€”
col_50STRINGโ€”
col_51STRINGโ€”
col_52STRINGโ€”
col_53STRINGโ€”
col_54STRINGโ€”
col_55STRINGโ€”
col_56STRINGโ€”
col_57STRINGโ€”
col_58STRINGโ€”
col_59STRINGโ€”
col_60STRINGโ€”
col_61STRINGโ€”
col_62STRINGโ€”
col_63STRINGโ€”