Run your SQL files with sqlrunner
I interact with PostgreSQL databases using psql, a basic but configurable
tool that is enough for most of the work I have to
do. I also
manage a collection of SQL files in order to display reports, troubleshoot
things on production systems, or many other usages.
These files use psql variables, set from the command line with -v:
$ cat /tmp/foo.sql
select :'foo';
$ psql -At -f /tmp/foo.sql
psql:/tmp/foo.sql:1: ERROR: syntax error at or near ":"
LINE 1: select :'foo';
$ psql -At -f /tmp/foo.sql -v foo=bar
bar
I needed something to easily manage this collection of files, being able to
list all of them with a description, as well as the list of variables they
support. So I built sqlrunner, using
Rust and 100% LLM-agent engineering. It works on top of psql.
sqlrunner examples
In addition to the README, here are some examples of the tool usage.
Listing, over the example/ directory of the repository (load
example.schema.sql first):
$ sqlrunner --sql-dir=example
FILE VARIABLES DESCRIPTION
audit.sql action, row_limit, table_name Audit trail of a table, ignoring quoted lookalikes
orders.sql end_date, start_date, status Orders of a period, by status
stats.sql User counts, total and last 30 days
users.sql user_id Details of one user
Setting config options as environment variables, then running a file:
$ export SQLRUNNER_SQL_DIR=example
$ export SQLRUNNER_DSN=postgresql://user@localhost/sqlrunner
$ sqlrunner stats.sql
psql --quiet \
-d postgresql://user@localhost/sqlrunner \
-f example/stats.sql
users │ recent
═══════╪════════
3 │ 2
(1 row)
Query with variable:
$ sqlrunner orders.sql status='in progress' start_date=2026-01-01 end_date=2026-02-01
psql --quiet \
-d postgresql://user@localhost/sqlrunner \
-v end_date=2026-02-01 \
-v start_date=2026-01-01 \
-v 'status=in progress' \
-f example/orders.sql
id │ status │ total
════╪═════════════╪════════
1 │ in progress │ 42.00
3 │ in progress │ 128.90
(2 rows)
Query with variable interactively set:
$ export SQLRUNNER_INTERACTIVE=true
$ sqlrunner orders.sql
end_date: 2026-02-01
start_date: 2026-01-01
status: in progress
psql --quiet \
-d postgresql://user@localhost/sqlrunner \
...
Also, sqlrunner supports completion of filenames and variables, which can be very time-saving for a hardcore user like me!
What was the development process?
I first started with a fresh git init and a simple
CLAUDE.md. Note
that I also have a personal CLAUDE.md with general rules like “Always add
unit tests”. For this project I made the experiment of keeping a history of the
prompts I wrote in a specific file:
PROMPTS.md.
I always use a verb at the beginning of these prompts and keep them single line. In the past I would have been worried about the quality of the code I wrote. Now I worry about the English of these prompts I share with you!
The commits have been the minimal unit of work for this project. I discarded or rewrote some of these, but most were fine. When Claude was working to implement one of the prompts, I was busy writing the next ones to keep the software factory smooth :)
By Thomas Martin