Skip to content
shellhacks.dev
Databases

Stop on the first error

Stop psql at the first failing statement with -v ON_ERROR_STOP=1, which also makes the exit status 3. By default it continues and exits 0.

1 min read
Summarize in AI

A migration script has three statements, the second fails, and psql still reports success.

Shell
printf 'CREATE TABLE t1 (id int);\nSELECT * FROM missing_table;\nCREATE TABLE t2 (id int);\n' > migrate.sql
psql -q -f migrate.sql; echo "default exit: $?"
psql -q -c "DROP TABLE IF EXISTS t1, t2" 2>/dev/null
psql -q -v ON_ERROR_STOP=1 -f migrate.sql; echo "ON_ERROR_STOP exit: $?"
psql -At -c "SELECT tablename FROM pg_tables WHERE tablename IN ('t1','t2') ORDER BY 1"
Text
ERROR:  relation "missing_table" does not exist
LINE 1: SELECT * FROM missing_table;
                      ^
default exit: 0
ERROR:  relation "missing_table" does not exist
LINE 1: SELECT * FROM missing_table;
                      ^
ON_ERROR_STOP exit: 3
t1

By default psql prints an error and goes on with the next statement, and its exit status reflects only whether it could run, so the first run finishes with status 0 even though a statement failed. Setting ON_ERROR_STOP makes it stop at the first error and exit with status 3, as the psql reference documents. The last query shows that t2 was never created in the second run.

The statements before the error were already committed, since each runs in its own transaction. Add -1 (--single-transaction) to wrap the whole file in one, so a failure undoes everything. A statement that uses CREATE INDEX CONCURRENTLY cannot run in a transaction block.

Share

More snippets

Databases

Dump one table

Dump one table with pg_dump -t name. The option takes a pattern, so -t orders does not match orders_archive but -t 'orders*' does, and quoting rules apply.

2 min read
Databases

Run SQL from a file

Run SQL from a file with psql -f. An error in the middle does not stop the file and the exit status stays 0, unless ON_ERROR_STOP is set to 1.

2 min read
Databases

Describe a table

Show a table's columns, indexes and foreign keys with the psql meta-command backslash d, and add a plus sign for storage and comments.

2 min read

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.