18

Say I have the files:

file1.sql
file2.sql
file3.sql

I need all three files to be executed in a single transaction. I'm looking for a bash script like:

psql -h hostname -U username dbname -c "
begin;
\i file1.sql
\i file2.sql
\i file3.sql
commit;"

This fails with an error: Syntax error at or near "\".

I also tried connecting to the DB first and then executing the fails, like that:

psql dbname
begin;
\i file1.sql
\i file2.sql
\i file3.sql
commit;

This also fails, because the 'begin' command executes only when the connection is terminated.

Is it possible to execute several .sql files in a single transaction using PostgreSQL and bash?

Edit:

The rough structure of each of the files is similar:

SET CLIENT_ENCODING TO 'WIN1251';
\i file4.sql
\i file5.sql
<etc>
RESET CLIENT_ENCODING;
7
  • you could build a single file to execute cat ing the files together with printf begin+end around Commented Jul 21, 2015 at 11:01
  • @amdixon Yes, I could, but each of the files also contain \i commands. So the result is going to be the same. Commented Jul 21, 2015 at 11:06
  • do you control (/are you generating) these files ? Commented Jul 21, 2015 at 11:07
  • @amdixon The files are automatically generated, I don't control them. Commented Jul 21, 2015 at 11:11
  • 1
    Either a sub-shell: (echo "BEGIN;"; cat file1.sql; cat file2.sql; ... echo "COMMIT;") | psql ... or use a here-document. Commented Jul 21, 2015 at 11:27

4 Answers 4

23

You can also use the -1 or --single-transaction option to execute all your scripts in a transaction:

cat file*.sql | psql -1
Sign up to request clarification or add additional context in comments.

Comments

13

Either use a sub-shell:

#!/bin/sh
 (echo "BEGIN;"; cat file1.sql; cat file2.sql; echo "COMMIT;") \
 | psql -U the_user the_database

#eof

or use a here-document:

#!/bin/sh
psql -U the_user the_database <<OMG
BEGIN;

\i file1.sql

\i file2.sql

COMMIT;
OMG

#eof

NOTE: in HERE-documents there will be no globbing, so file*sql will not be expanded. Shell-variables will be expanded, even within quotes.

1 Comment

Yes, the sub-shell works, because of the pipe. Didn't think to pipe the files into psql. Thank you for the help.
5

I'd create new files for the startup (start transaction, set encoding etc) and finish (commit).

Then run something like:

cat startup.sql file*.sql finish.sql | psql dbname

1 Comment

I used the first solution, but reckon this one would work either.
3

FYI, for Windows command line:

FOR /F "usebackq" %A IN (`dir *.sql /b/a-d`) DO psql -f %A

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.