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_dumpto 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_dumpto 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.-Cor--create: Include theCREATE DATABASEcommand in the output file. This is helpful if you want the dump file to create the database when you restore it.-cor--clean: Include commands toDROPexisting database objects before creating new ones. Useful for ensuring a clean schema import.--if-exists: Use with--cleanto addIF EXISTSclauses to theDROPcommands, 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-existsBasic 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-existsCopying 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-sor--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 -CCopying All Database Schemas
# Export all database schemas
pg_dumpall -s \
-U postgres \
-f all_schemas_dump.sql \
-h localhost \
-p 5432 \
-CDirectly 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
.pgpassfile 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_dumpallcommand:-C: IncludesCREATE DATABASEstatements in the output.-h <source_host>: Hostname of the source server. Uselocalhostif 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_dumpallto the input ofpsql.PGPASSWORD=your_target_password psql -h <target_host> -U <target_user> -d postgres -p <target_port>: This is thepsqlcommand: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. Uselocalhostif 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 thepostgresdatabase on the target server. You can use any existing database aspg_dumpalloutput includesCREATE DATABASEcommands.-p <target_port>: Port of the target server (e.g.,5433in your example).
Important Notes for Direct Pipe Copy:
- Password Security: Using
PGPASSWORDin 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
psqlpart of the command, we connect to thepostgresdatabase on the target server. This is just a starting point; thepg_dumpalloutput will containCREATE DATABASEstatements 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.