When working with PostgreSQL, you might need to execute multiple SQL scripts in sequence. This is common during database initialization, migration processes, or when applying modular schema changes. Manually running each file isn't practical, especially in automated environments.
The simplest approach is using PostgreSQL's \i
meta-command within psql:
-- master_file.sql
\i /path/to/aaa.sql
\i /path/to/bbb.sql
\i /path/to/ccc.sql
For more control and error handling, create a shell script:
#!/bin/bash
psql -U username -d dbname -f aaa.sql
psql -U username -d dbname -f bbb.sql
psql -U username -d dbname -f ccc.sql
For transactional execution where you want all scripts to succeed or fail together:
-- master_file.sql
BEGIN;
\i aaa.sql
\i bbb.sql
\i ccc.sql
COMMIT;
You can add logic to check if scripts should run:
-- master_file.sql
DO $$
BEGIN
IF (SELECT count(*) FROM information_schema.tables WHERE table_name = 'some_table') = 0 THEN
\i aaa.sql
END IF;
\i bbb.sql
\i ccc.sql
END
$$;
By default, psql will stop on first error. To continue after errors:
psql -v ON_ERROR_STOP=0 -f master_file.sql
When working with PostgreSQL database deployments, it's common to have multiple SQL files containing schema definitions, data migrations, or stored procedures. Executing them individually can be time-consuming and error-prone during deployments or development setup.
The simplest approach is using PostgreSQL's built-in \\i
command in psql:
-- master_script.sql \\i /path/to/aaa.sql \\i /path/to/bbb.sql \\i /path/to/ccc.sql
For more control, create a shell script that pipes files to psql:
#!/bin/bash psql -U username -d dbname -f aaa.sql psql -U username -d dbname -f bbb.sql psql -U username -d dbname -f ccc.sql
Important: By default, each file executes in its own transaction. To wrap everything in a single transaction:
BEGIN; \\i aaa.sql \\i bbb.sql \\i ccc.sql COMMIT;
For production deployments, consider adding error checking:
\\set ON_ERROR_STOP on \\i aaa.sql \\i bbb.sql \\i ccc.sql
For advanced scenarios with many files, use a PL/pgSQL script with dynamic SQL:
DO $$ DECLARE file_list text[] := ARRAY['aaa.sql','bbb.sql','ccc.sql']; file_name text; BEGIN FOREACH file_name IN ARRAY file_list LOOP EXECUTE format('\\i %s', file_name); END LOOP; END $$;
For portable scripts across environments:
\\set base_path '/path/to/sql/files' \\i :base_path/aaa.sql \\i :base_path/bbb.sql \\i :base_path/ccc.sql