psql script execution not returning error - postgresql

I am trying to execute multiple sql scripts using psql. I created one master script with all the scripts to be executed as below. I want all the scripts to succeed or fail together.
master.sql
BEGIN;
\i one.sql
\i two.sql
\i three.sql
COMMIT;
I am trying to catch the error code of psql to determine if it success. When i query for ?$ it always returns 0. I figured when add ON_ERROR_STOP=1 to command it returns proper error code. Problem with this approach if the error happens in three.sql it does not roll back one.sql and two.sql transactions.
psql -U postgres -h localhost -d test -v ON_ERROR_STOP=1 -f master.sql
What would be correct approach to find out if script executed successfully.

Related

Can a connection command be embedded in a psql script?

I am running a script interactively to test it. The meta-command \c is not playing well with the standard sql commands: it seems to want to be run by itself. Here is what happens when it is run in the script
\set username steve
\c pubkey :username
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO :username;
GRANT ALL PRIVILEGES ON ALL sequences IN SCHEMA public TO :username;
Results:
invalid integer value "ALL" for connection option "port"
Previous connection kept
But if the "\c" command is run by itself then the subsequent grant's are successful. Is there a way to embed the "\c" connection commands in a psql script?
It seems that running in psql has different behavior than in a script itself: running the above from the command line using -f does work
psql postgres -f create_dbs.sql -a > db.out 2>&1
Whereas running the '\c` command from psql seems to need to be isolated.

Problem executing a PostgreSQL SQL script on Ubuntu Linux

I would like to execute a SQL script that will create a database in Postgres. It produces the message:
bash: syntax error near unexpected token 'newline'
The script is:
Ā postgres#tom: /home/tom$ psql -1q test test <script.sql 2>
If you want to redirect standard error to standard output, you should run
psql -1q -d test -U test -f script.sql 2>&1

how to stop and exit from the postgresql restoration if an error occurs

we are trying to restore PostgreSQL schema dumps into a database from the command line using the below command
psql -U postgres -d dbname < filename
and we are getting response in command line during the restoration like below
SET
SET
SET
SET
SET
CREATE SCHEMA
ALTER SCHEMA
.
.
.
.
and going on
My question is, if there are some errors happened in between the restoration and restoration continues to go on, how to detect that error without scrolling through these entire response through command line? or
Is there anyway to automatically stop and exit from the restoration process if an error occurs?
We are using PostgreSQL 10
There are two things you can do:
First run the entire script as a single transaction:
psql --single-transaction -U postgres -d dbname < filename
Additionally you can configure psql to abort if an error occurs:
\set ON_ERROR_STOP on
You would need to put the \set into the file you are running.
Alternatively, if you always want that behavior, put it into ~/.psqlrc

psql, can't copy db content to another - cannot run inside a transaction block-

I'd like to copy the content of my local machine to my remote one (inside a docker).
For some reason, it is more complicated that I was expected:
When I try to copy the data to the remote one, I get this "ERROR: CREATE DATABASE cannot run inside a transaction block".
Ok... So I get into my docker container, added the rule \set AUTOCOMMIT inside. But I still get this error.
This is the command I did:
// backup
pg_dump -C -h localhost -U postgres woof | xz >backup.xz
and then in my remote computer:
xz -dc backup.xz | docker exec -i -u postgres waf-postgres psql --set ON_ERROR_STOP=on --single-transaction
But each time I get this "CREATE DATABASE cannot run inside a transaction block" no matter what I try. Even if I put the autocommit to "on".
Here my problem: I don't know what a transaction block is. And I don't understand why copying one db to another need to be so hard pain: My remote db is empty. So why there is so much fuss and why psql just can't force what I want?
My aim is just to copy my local db to the remote one.
what happens here is: you add CREATE DATABASE statement with -C key and then try to run psql with --single-transaction, so the content of script are wrapped to BEGIN;...END;, where you can't use CREATE DATABASE
So iether remove -C and run psql against existing database, or remove --single-transaction for psql. Make decision based on what you really need...
from man pg_dump:
-C
--create
Begin the output with a command to create the database itself and reconnect to the created database. (With a script of this
form, it doesn't matter which database in the destination installation
you connect to before
running the script.) If --clean is also specified, the script drops and recreates the target database before reconnecting to
it.
from man psql:
--single-transaction
This option can only be used in combination with one or more -c and/or -f options. It causes psql to issue a BEGIN command
before the first such option and a COMMIT command after the last one, thereby wrapping all the commands into a single
transaction. This ensures that either all the commands complete successfully, or no changes are applied.

Deploy postgres via jenkins - continuous integration/deployment

I got my database dump (tables, functions, triggers etc) in *.sql files.
At this moment I am deploying them via jenkins, by passing execute shell command:
sudo -u postgres psql -d my_db < /[path_to_my_file].sql
The problem is, that if something is wrong in my sql file, build finishes as SUCCESS. I would like to got information immediately if something fails, without looking into log and checking if every command executed succesfully.
Is it possible (and how if the answer is 'yes') to deploy postgres database via jenkins other way?
I changed my execution command to:
sudo -u postgres psql -v ON_ERROR_STOP=1 -d my_db < [path_to_file].sql
Make sure you have set
set -e
Before running the command.
If that does not work, I'd look at the return code from the command above. That can be done by running
echo $?
right after the command.
If that gives you a zero when it fails it's postgres fault (sice it should return with something else than 0 on fail).
Perhaps there is a postgres flag to fail on wrong input.
EDIT:
-v ON_ERROR_STOP=1
As a flag to postgres should make postgres fail on errors