Copying PostgreSQL Databases Schema and Data
When working with PostgreSQL, you’ll often need to copy databases. Whether it’s for backups, setting up development environments, or migrating between servers, understanding how to efficiently copy your PostgreSQL databases is crucial. This post focuses on copying PostgreSQL databases of the same version, covering schema-only copies, full copies (schema and data), and server-to-server transfers.
Copying Schema Only
If you need to replicate just the structure of your database without the data, pg_dump
with the --schema-only
option is your go-to tool. This is incredibly useful for:
- Setting up development or testing databases.
- Version controlling database schema changes.
- Preparing for data migration by creating the target schema first.
Using pg_dump --schema-only
The basic command structure is:
pg_dump --schema-only -U <username> -d <database_name> -f <output_file.sql>
Let’s break down the key options:
--schema-only
: This is the essential flag that tellspg_dump
to only export the schema (table definitions, functions, indexes, etc.) and not the data itself.-U <username>
: Specifies the PostgreSQL username to connect with.-d <database_name>
: The name of the source database you want to copy.-f <output_file.sql>
: The name of the file where the schema SQL will be saved.
Enhancing Your Schema Export
Here are some useful options to add to your pg_dump
command:
-W
: Forcepg_dump
to prompt for a password.-h <hostname>
: Specify the hostname of the PostgreSQL server if it’s not local.-p <port>
: Specify the port number if PostgreSQL is running on a non-default port.-C
or--create
: Include theCREATE DATABASE
command in the output file. This is helpful if you want the dump file to create the database when you restore it.-c
or--clean
: Include commands toDROP
existing database objects before creating new ones. Useful for ensuring a clean schema import.--if-exists
: Use with--clean
to addIF EXISTS
clauses to theDROP
commands, preventing errors if objects don’t exist in the target database.--table=<pattern>
and--exclude-table=<pattern>
: For selectively including or excluding specific tables based on patterns. For example,--table=public.users*
would include tables starting with “users” in the public schema.
Example Command (Single Database Schema Only):
pg_dump --schema-only -U db_admin -d source_db -f schema_only_dump.sql -h db.example.com -p 5432 -C -c --if-exists
Basic Schema Export
# Basic schema-only export
pg_dump --schema-only \
-U <username> \
-d <database_name> \
-f <output_file.sql>
Advanced Schema Export Options
# Enhanced schema export with additional options
pg_dump --schema-only \
-U db_admin \
-d source_db \
-f schema_only_dump.sql \
-h db.example.com \
-p 5432 \
-C \
-c \
--if-exists
Copying All Databases Schema Only
To export the schema of all databases in your PostgreSQL cluster (excluding template databases like template0
and template1
), you can use pg_dumpall
with the -s
(or --schema-only
) option.
Using pg_dumpall --schema-only
pg_dumpall -s -U <username> -f all_schemas_dump.sql
-s
or--schema-only
: Exports only the schema of all databases.-U <username>
: Specifies the PostgreSQL superuser username (required forpg_dumpall
).-f <all_schemas_dump.sql>
: The output file for all schemas.
Example Command (All Databases Schema Only):
pg_dumpall -s -U postgres -f all_schemas_dump.sql -h localhost -p 5432 -C
Copying All Database Schemas
# Export all database schemas
pg_dumpall -s \
-U postgres \
-f all_schemas_dump.sql \
-h localhost \
-p 5432 \
-C
Directly Copying All Database Schemas to a Target Server
You can combine pg_dumpall
and psql
with a pipe to directly copy all database schemas to a target server without saving to a local file first. This is efficient for server-to-server schema replication.
Example Command (Direct Schema Copy to Target):
export PGPASSWORD=your_source_password # Set password for source user (if needed)
pg_dumpall -C -h <source_host> -p <source_port> -U <source_user> -s | PGPASSWORD=your_target_password psql -h <target_host> -U <target_user> -d postgres -p <target_port>
⚠️ Security Warning: The examples in this post use plain text passwords for demonstration purposes. In production environments, you should use
.pgpass
file or connection service files for secure password management.
Let’s break down this command:
export PGPASSWORD=your_source_password
: Sets the password for the source PostgreSQL user as an environment variable. Important: While convenient, be cautious about exposing passwords in your shell history. Consider more secure methods for production environments.pg_dumpall -C -h <source_host> -p <source_port> -U <source_user> -s
: This is thepg_dumpall
command:-C
: IncludesCREATE DATABASE
statements in the output.-h <source_host>
: Hostname of the source server. Uselocalhost
if it’s on the same machine.-p <source_port>
: Port of the source server (default is 5432).-U <source_user>
: PostgreSQL superuser on the source server (e.g.,postgres
).-s
: Specifies schema-only dump.
|
: The pipe symbol directs the output ofpg_dumpall
to the input ofpsql
.PGPASSWORD=your_target_password psql -h <target_host> -U <target_user> -d postgres -p <target_port>
: This is thepsql
command:PGPASSWORD=your_target_password
: Sets the password for the target PostgreSQL user.psql
: The PostgreSQL command-line client.-h <target_host>
: Hostname of the target server. Uselocalhost
if it’s the same machine but a different port.-U <target_user>
: PostgreSQL user on the target server (e.g.,postgres
).-d postgres
: Connect to thepostgres
database on the target server. You can use any existing database aspg_dumpall
output includesCREATE DATABASE
commands.-p <target_port>
: Port of the target server (e.g.,5433
in your example).
Important Notes for Direct Pipe Copy:
- Password Security: Using
PGPASSWORD
in environment variables is shown for example purposes. For production, explore more secure password management methods. - User Permissions: Ensure the source user has sufficient privileges to dump all databases and the target user has privileges to create databases and schemas on the target server.
- Target Database: In the
psql
part of the command, we connect to thepostgres
database on the target server. This is just a starting point; thepg_dumpall
output will containCREATE DATABASE
statements to create all the databases on the target server based on the dumped schemas.
Restoring the Schema
To import the schema into a new database from a file (e.g., all_schemas_dump.sql
), use psql
:
psql -U <username> -d <target_database_name> -f <all_schemas_dump.sql>
If your pg_dumpall
command included -C
, the dump file will attempt to create databases if they don’t exist.