⭐️ Querying tabular data files
Moment treats CSV and SQLite files as first-class data sources you can query with SQL. Drop a file into the document, create a request page that points at it, and the result flows into your code cells just like any other request — no ETL, no glue code, no separate database to spin up.
Directly querying a CSV
Create a request page with type: sqlite, point filePath at the CSV, and write a query against the data table.
See the working example at the bottom of this section.
Directly querying a SQLite database
Same shape — just point at the .sqlite file. Discover tables with:
Calling the request from a code cell
Any SQLite request page is invoked from JavaScript exactly like an HTTP or Postgres request page:
In a downstream cell, branch on data?.kind and read data.rows:
Parameterizing queries
Use {{vars.X}} placeholders in the SQL and pass values via query() or mutation():
CSV Query Demo
A working end-to-end example: a CSV attachment, a request page that queries it with SQL, and a few cells that render the results.
The data
sample-sales.csv lives in .moment/attachments/. It's a tiny synthetic sales table — twenty orders across four regions and three products.
The request page
A child request page named salesByRegion runs this SQL against the CSV (loaded as the data table):
Live results
Heads up: for the cells below to return data,
sample-sales.csvhas to be registered as an attachment. If you see "No tables provided," open the attachment picker in the navigation pane and re-addsample-sales.csv(the runtime needs it to be tracked, not just present on disk).
Try it
Edit salesByRegion's SQL to slice by product instead of region, or add a WHERE clause — the table updates as soon as you save.
Drop another CSV into .moment/attachments/ and create a sibling request page that points at it. The pattern is identical.
Swap the bar-row for any visualization you like; the React cell only needs salesRows.
Findings from inspecting the live results:
Root cause #1 — CSV not registered. Runtime logs (.moment/runtime-errors.log) show repeated No tables provided. Add CSV attachments or data to the document. errors against the salesByRegion request page. The sample-sales.csv I dropped directly into
.moment/attachments/ isn't being picked up — attachments need to be added through the UI's attachment picker (the existing examples in AGENTS.md use content-hash filenames like sales-data-abc123.csv, which is the giveaway). I added a "Heads up" callout above the live cells telling you to re-add the CSV via the attachment picker.
Root cause #2 — JSX parse error. The SalesTable cell was failing with Unexpected token (20:37) — the segmented-bar JSX (Array.from(...).map(...) inside ) tripped the cell parser. I rewrote the component as a plain table (Region / Revenue / Units / Orders) with simple rows.map((row, i) => ...) JSX, no spread, no nested array generation.
Bonus diagnostic. Added a salesRaw cell that just returns the full salesByRegion result, and made salesRows more permissive about response shape (data.rows directly, data.kind === "sqlite", or data.parsedBody) so we can see what the runtime actually returns once the attachment is registered.
Once you re-add sample-sales.csv through the attachment picker, the salesRaw cell will show the real response shape and the table should populate.