What's the correct way to copy entire database (its structure and data) to a new one in pgAdmin?
What's the correct way to copy entire database (its structure and data) to a new one in pgAdmin?
Postgres allows the use of any existing database on the server as a template when creating a new database. I'm not sure whether pgAdmin gives you the option on the create database dialog but you should be able to execute the following in a query window if it doesn't:
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
Still, you may get:
ERROR: source database "originaldb" is being accessed by other users
To disconnect all other users from the database, you can use this query:
SELECT pg_terminate_backend(pg_stat_activity.pid) FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'originaldb' AND pid <> pg_backend_pid();
Don't know about pgAdmin, but pgdump gives you a dump of the database in SQL. You only need to create a database by the same name and do
psql mydatabase < my dump
to restore all of the tables and their data and all access privileges.
Here's the whole process of creating a copying over a database using only pgadmin4 GUI (via backup and restore)
Postgres comes with Pgadmin4. If you use macOS you can press CMD+SPACE and type pgadmin4 to run it. This will open up a browser tab in chrome.
Do this by rightclicking the database -> "backup"
Like test12345. Click backup. This creates a binary file dump, it's not in a .sql format
There should be a popup at the bottomright of your screen. Click the "more details" page to see where your backup downloaded to
In this case, it's /users/vincenttang
Assuming you did steps 1 to 4 correctly, you'll have a restore binary file. There might come a time your coworker wants to use your restore file on their local machine. Have said person go to pgadmin and restore
Do this by rightclicking the database -> "restore"
Make sure to select the file location manually, DO NOT drag and drop a file onto the uploader fields in pgadmin. Because you will run into error permissions. Instead, find the file you just created:
You might have to change the filter at bottomright to "All files". Find the file thereafter, from step 4. Now hit the bottomright "Select" button to confirm
You'll see this page again, with the location of the file selected. Go ahead and restore it
If all is good, the bottom right should popup an indicator showing a successful restore. You can navigate over to your tables to see if the data has been restored propery on each table.
Should step 9 fail, try deleting your old public schema on your database. Go to "Query Tool"
Execute this code block:
DROP SCHEMA public CASCADE; CREATE SCHEMA public;
Now try steps 5 to 9 again, it should work out
EDIT - Some additional notes. Update PGADMIN4 if you are getting an error during upload with something along the lines of "archiver header 1.14 unsupported version" during restore
From the documentation, using createdb or CREATE DATABASE with templates is not encouraged:
Although it is possible to copy a database other than template1 by specifying its name as the template, this is not (yet) intended as a general-purpose “COPY DATABASE” facility. The principal limitation is that no other sessions can be connected to the template database while it is being copied. CREATE DATABASE will fail if any other connection exists when it starts; otherwise, new connections to the template database are locked out until CREATE DATABASE completes.
pg_dump or pg_dumpall is a good way to go for copying database AND ALL THE DATA. If you are using a GUI like pgAdmin, these commands are called behind the scenes when you execute a backup command. Copying to a new database is done in two phases: Backup and Restore
pg_dumpall saves all of the databases on the PostgreSQL cluster. The disadvantage to this approach is that you end up with a potentially very large text file full of SQL required to create the database and populate the data. The advantage of this approach is that you get all of the roles (permissions) for the cluster for free. To dump all databases do this from the superuser account
pg_dumpall > db.out
and to restore
psql -f db.out postgres
pg_dump has some compression options that give you much smaller files. I have a production database I backup twice a day with a cron job using
pg_dump --create --format=custom --compress=5 --file=db.dump mydatabase
where compress is the compression level (0 to 9) and create tells pg_dump to add commands to create the database. Restore (or move to new cluster) by using
pg_restore -d newdb db.dump
where newdb is the name of the database you want to use.
PostgreSQL uses ROLES for managing permissions. These are not copied by pg_dump. Also, we have not dealt with the settings in postgresql.conf and pg_hba.conf (if you're moving the database to another server). You'll have to figure out the conf settings on your own. But there is a trick I just discovered for backing up roles. Roles are managed at the cluster level and you can ask pg_dumpall to backup just the roles with the --roles-only command line switch.
Using pgAdmin, disconnect the database that you want to use as a template. Then you select it as the template to create the new database, this avoids getting the already in use error.
If you want to copy whole schema you can make a pg_dump with following command:
pg_dump -h database.host.com -d database_name -n schema_name -U database_user --password
And when you want to import that dump, you can use:
psql "host=database.host.com user=database_user password=database_password dbname=database_name options=--search_path=schema_name" -f sql_dump_to_import.sql
More info about connection strings: https://www.postgresql.org/docs/current/libpq-connect.html#LIBPQ-CONNSTRING
Or then just combining it in one liner:
pg_dump -h database.host.com -d postgres -n schema_name -U database_user --password | psql "host=database.host.com user=database_user password=database_password dbname=database_name options=--search_path=schema_name”
Disconnect the "templated" database that you want to use as a template.
Run 2 queries as below
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = 'TemplateDB' AND pid <> pg_backend_pid();
(The above SQL statement will terminate all active sessions with TemplateDB and then you can now select it as the template to create the new TargetDB database, this avoids getting the already in use error.)
CREATE DATABASE 'TargetDB'
WITH TEMPLATE='TemplateDB'
CONNECTION LIMIT=-1;
pgAdmin4:
1.Select DB you want to copy and disconnect it
Rightclick "Disconnect DB"
2.Create a new db next to the old one:
Hit create and just left click on the new db to reconnect.
New versions of pgAdmin (definitely 4.30) support creating new databases from template. All you need to populate are new database name and existing template database.
CREATE DATABASE newdb WITH TEMPLATE originaldb OWNER dbuser;
If you have using Ubuntu. 1 way createdb -O Owner -T old_db_name new_db_name
2 way createdb test_copy pg_dump old_db_name | psql test_copy