You have a JSON export and need it in a database: seed data, a migration, test fixtures for staging. Pasting values by hand doesn't scale, and most online converters want you to upload data you'd rather keep local. Here's the terminal-first path.
Given users.json:
[
{ "name": "Alice", "age": 32 },
{ "name": "Bob", "age": 25 }
]
$ npx github:mahope/transmute users.json --output sql --table users -- Generated by Transmute INSERT INTO "users" ("name", "age") VALUES ('Alice', 32), ('Bob', 25);
The same works for CSV and YAML input — pick the format flag that matches your source:
$ npx github:mahope/transmute people.csv --output sql --table people $ npx github:mahope/transmute config.yaml --format yaml --output sql
Because transformation happens before serialization, you filter, sort and reshape in the same command. Only adults, names only:
$ npx github:mahope/transmute users.json --pipe '[{"op":"filter","expr":"item.age > 26"},{"op":"pick","fields":["name"]}]' --output sql --table adults -- Generated by Transmute INSERT INTO "adults" ("name") VALUES ('Alice');
This is where a converter beats a one-off script: the same pipeline that cleans the data also decides what gets inserted.
O'Brien becomes 'O''Brien' — the standard SQL doubling, valid in PostgreSQL, MySQL and SQLite. A string-concatenation approach produces broken statements on exactly this input.null, missing fields and empty strings all become NULL — not the string "null".$ npx github:mahope/transmute mixed.json --output sql -- Generated by Transmute INSERT INTO "my_table" ("a") VALUES (1), (NULL);
import json rows = json.load(open("users.json")) cols = list(rows[0]) for row in rows: vals = ", ".join( "NULL" if row.get(c) is None else str(row[c]) if isinstance(row.get(c), (int, float)) else "'" + str(row[c]).replace("'", "''") + "'" for c in cols ) print(f'INSERT INTO users ({", ".join(cols)}) VALUES ({vals});')
Zero dependencies — but note what you're signing up for: column inference from the first row (later rows with extra keys silently drop data), manual type handling, and no batching. Fine for ten rows; error-prone for ten thousand.
Exports headed for a database often contain customer data, tokens or internal IDs. Uploading them to a random website to get SQL back means trusting a third party with exactly the data you were about to put somewhere permanent. A CLI that runs locally has nowhere to send it.
A few thousand INSERT lines load fine through any client (psql -f seed.sql). Past tens of thousands of rows, wrap the output in a single transaction so a failure rolls back cleanly instead of leaving half a table:
$ { echo 'BEGIN;'; npx github:mahope/transmute big.json --output sql; echo 'COMMIT;'; } > seed.sql $ psql mydb -f seed.sql
order, group) are quoted with double quotes, which works in PostgreSQL/SQLite; MySQL needs ANSI_QUOTES mode or backticks.The Transmute CLI is free (npx github:mahope/transmute). The desktop app adds an interactive pipeline builder, live preview and batch processing — one-time $19, no subscription.
More guides: CSV to JSON · Joining two files by a key