How to restore postgres database into another database name - postgresql

I use the postgres today
and got a problem
I dump the database that way
pg_dump zeus_development -U test > zeus_development.dump.out
what if I wnat to restore to another database zeus_production
How could I do?

Simple, first create your database using template0 as your template database:
createdb -U test -T template0 zeus_production
Then, restore your dump on this database:
psql -U test zeus_production -f /path/to/zeus_development.dump.out
When restoring, always use template0 explicit, as it is always an empty and unmodifiable database. If you don't use an explicit template, PostgreSQL will assume template1, and if it has some objects, like a table or function that your dumped database already has, you will get some errors while restoring.
Nonetheless, even if you were restoring on a database with the same name (zeus_development) you should create (or recreate) it the same way. Unless you used -C option while dumping (or -C of pg_restore if using a binary dump), which I don't recommend, because will give you less flexibility (like restoring on a different database name).

The PostgresSQL documentation has influenced me to use the custom format. I've been using it for years and it seems to have various advantages but your mileage may vary. That said, here is what worked for me:
pg_restore --no-owner --dbname postgres --create ~/Desktop/pg_dump
psql --dbname postgres -c 'ALTER DATABASE foodog_production RENAME TO foodog_development'
There was no foodog_development nor foodog_production databases existing before the sequence.
This restores the database from the dump (~/Desktop/pg_dump) which will create it with the name it was dumped as. The rename names the DB to whatever you want.
The --no-owner may not be needed if your user name is the same on both machines. In my case, the dump was done as user1 and the restore done as user2. The new objects need to be owned by user2 and --no-owner achieves this.

Isn't it easier to simply do the following?
createdb -U test -T zeus_development zeus_production

This has an answer on dba.stackexchange, which I reproduce here:
Let's define a few variables to make the rest easier to copy/paste
old_db=my_old_database
new_db=new_database_name
db_dump_file=backups/my_old_database.dump
user=postgres
The following assumes that your backup was created with the "custom" format like this:
pg_dump -U $user -F custom $old_db > "$db_dump_file"
To restore $db_dump_file to a new database name $new_db :
dropdb -U $user --if-exists $new_db
createdb -U $user -T template0 $new_db
pg_restore -U $user -d $new_db "$db_dump_file"

Here's a hacky way of doing it, that only works if you can afford the space and time to use regular .sql format, and if you can safely sed out your database name and user.
$ pg_dump -U my_production_user -h localhost my_production > my_prod_dump.sql
$ sed -i 's/my_production_user/my_staging_user/g' my_prod_dump.sql
$ sed -i 's/my_production/my_staging/g' my_prod_dump.sql
$ mv my_prod_dump.sql my_staging_dump.sql
$ sudo su postgres -c psql
psql> drop database my_staging;
psql> create database my_staging owner my_staging_user;
psql> \c my_staging;
psql> \i my_staging_dump.sql

If your dump does not include the name, the restore will use the DB defined in DESTINATION. Both SOURCE and DESTINATION are Connection URLs.
Dump without --create
pg_dump \
--clean --if-exists \
--file ${dump_path} \
--format=directory \
--jobs 5 \
--no-acl \
--no-owner \
${SOURCE}
Restore without --create
pg_restore \
--clean --if-exists \
--dbname=${DESTINATION} \
--format=directory \
--jobs=5 \
--no-acl \
--no-owner \
$dump_path

Related

Restoring DB for PostgreSQL [duplicate]

I take backup using
pg_dump db_production > postgres_db.dump
and then I copy it to localhost using scp.
Now when I import on my local db it gives an error
pg_restore: [archiver] input file appears to be a text format dump. Please use psql.
by using commad line
pg_restore -d db_development postgres_db.dump
From the pg_dump documentation:
Examples
To dump a database called mydb into a SQL-script file:
$ pg_dump mydb > db.sql
To reload such a script into a (freshly created) database named newdb:
$ psql -d newdb -f db.sql
To dump a database into a custom-format archive file:
$ pg_dump -Fc mydb > db.dump
To dump a database into a directory-format archive:
$ pg_dump -Fd mydb -f dumpdir
To reload an archive file into a (freshly created) database named newdb:
$ pg_restore -d newdb db.dump
From the pg_restore documentation:
Examples
Assume we have dumped a database called mydb into a custom-format dump file:
$ pg_dump -Fc mydb > db.dump
To drop the database and recreate it from the dump:
$ dropdb mydb
$ pg_restore -C -d postgres db.dump
The answer above didn't work for me, this worked:
psql db_development < postgres_db.dump
In order to create a backup using pg_dump that is compatible with pg_restore you must use the --format=custom / -Fc when creating your dump.
From the docs:
Output a custom-format archive suitable for input into pg_restore.
So your pg_dump command might look like:
pg_dump --file /tmp/db.dump --format=custom --host localhost --dbname my-source-database --username my-username --password
And your pg_restore command:
pg_restore --verbose --clean --no-acl --no-owner --host localhost --dbname my-destination-database /tmp/db.dump
For me when i try to restore from remote host i used
psql -U username -p 5432 -h 10.10.10.1 -d database < db.dump
worked fine. And if not remote just following command worked.
psql -d database < db.dump
For me, It's working like this one.
C:\Program Files\PostgreSQL\12\bin> psql -U postgres -p 5432 -d dummy -f C:\Users\Downloads\d2cm_test.sql
If you restore .SQL file.
Create a new database in pgAdmin.
Go to the terminal and navigate the folder/directory where your .sql file is located. And then write the following command in terminal.
Syntax:
supername user postgres psql newDatabasename < inputfile.sql
Examaple:
sudo -u postgres psql newDb < restoreDb.sql
I've got same error when tried to backup db with DBeaver. If anyone uses DBeaver interface instead of command line on Windows, make sure your selected format as tar during backup and restore settings.
If you have a full DB dump:
PGPASSWORD="your_pass" psql -h "your_host" -U "your_user" -d "your_database" -f backup.sql
If you have schemas kept separately, however, that won't work. Then you'll need to disable triggers for data insertion, akin to pg_restore --disable-triggers. You can then use this:
cat database_data_only.gzip | gunzip | PGPASSWORD="your_pass" psql -h "your_host" -U root "your_database" -c 'SET session_replication_role = replica;' -f /dev/stdin
On a side note, it is a very unfortunate downside of postgres, I think. The default way of creating a dump in pg_dump is incompatible with pg_restore. With some additional keys, however, it is. WTF?
if you use pg_dump with -Fp to backup in plain text format, use following command:
cat db.txt | psql dbname
to copy all data to your database with name dbname
psql -U <username> -d <database-name> -h <host-name> -f <backup.sql>
Providing a simple one line answer which worked for me and will work for you too for most cases
psql -U username -d database_name < dump_file.sql
If above gives role related errors then replace username with postgres.
psql -U postgres -d database_name < dump_file.sql
Probably when you create a backup you want to restore it in another network or create a remote restoration.
We need to create a backup file using the --format=custom [-Fc] to restore it using pg_restore. We can use a connection string postgresql://<user>:<pass>#localhost:5432/<dbname> and replace <user>, <pass>, and <dbname> with your information.
pg_dump -v -Fc \
postgresql://<user>:<pass>#localhost:5432/<dbname> \
> db-20211122-163508.sql
To restore we will call it using --clean [-c] and --create [-C] to drop the database before restoring. Replace <user>, <host>, <port>, and <dbname> with your information.
pg_restore -vcC \
-U <user> \
-h <host> \
-p <port> \
-d <dbname> \
< db-20211122-163508.sql
If you backup with this way, I think this will be more easy to import database.
pg_dump -h (remote db address) -a --column-inserts -U postgres (database name) > (file name).sql
For import,
psql
-f (file name).sql
--host (remote db address)
--port 5432
--username postgres
--password (your password)
--dbname (database you want to import)
I've been struggling with this as well. This is the combination of dump & restore commands that worked for me:
pg_dump -Ft -C -h database_host -U username database > DATA.dump
To restore
pg_restore -x --no-owner -d database DATA.dump
Remove the -x flag if you want to keep the same access privileges (ACLs) in your DB. You must have the same roles and users in the database for this.
https://www.postgresql.org/docs/15/app-pgdump.html
https://www.postgresql.org/docs/15/app-pgrestore.html
here is the solution,
pg_restore -U username -p 5432 -h 10.10.10.1 -d database_name < dump_file

How to compare a schema defined in a file with actual schema running on DB?

I'm running a PostgreSQL DB and want to compare the schema defined in schema.sql with the schema that is created on the DB on a regular basis. I.e. to verify that no manual changes on the remote are applied or that schema.sql actually reflects what's running on the DB.
What I'm currently doing is roughly:
create a dump from schema.sql using pg_virtualenv:
$ pg_virtualenv sh -c 'psql -U $PGDATABASE -f schema.sql
$ pg_dump --schema-only --no-comments --no-owner --no-privileges --schema=public -U $PGDATABASE -f schema_local.sql'
create a dump from the remote
$ pg_dump --schema-only --no-comments --no-owner --no-privileges --schema=public -U $PGREMOTE -f schema_upstream.sql
strip out comments, SET, emtpy lines, etc. and diff them
$ diff -u <(grep -Ev '^--|^SET|^$$' schema_local.sql) <(grep -Ev '^--|^SET|^$$' schema_upstream.sql)
That works reasonably well and I can easily spot schema changes in the diff if they occur. But the solution seems a bit hacky and I wonder if there's a better way to achieve the same thing?

clone postgres database with new name

I have a users-production database on 157.157.35.333
I would like to clone it to another host as users-sandbox
here is what I tried:
PRODUCTION_HOST=111.111.11.111
SANDBOX_HOST=222.222.22.222
echo "creating db on sanbox"
psql -h ${SANDBOX_HOST} -U postgres -c "CREATE DATABASE \"users-sandbox\";"
pg_dump -h ${PRODUCTION_HOST} -U postgres -d users-production -F c -b -v | \
pg_restore -C -c -h ${SANDBOX_HOST} -U postgres -d users-sandbox -v
but this creates the database with the old name
how do I create with a new name?
https://www.postgresql.org/docs/current/static/app-pgrestore.html
-d dbname
Connect to database dbname and restore directly into the database.
but!
-C
--create
Create the database before restoring into it. If --clean is also
specified, drop and recreate the target database before connecting to
it.
When this option is used, the database named with -d is used only to
issue the initial DROP DATABASE and CREATE DATABASE commands. All data
is restored into the database name that appears in the archive.
so remove -C from pg_restore arguments...
(formatting of quotes mine)

psql equivalent for pg_restore for .sql files

I ONLY dump my databases as *.sql files not *.dump files. As a result NONE of the pg_restore commands work. I've been reading through answers and I swear most people have a reading disability lol
I am asking for the equivalent in psql for a common pg_restore commandLine method to restore a database.
I have no intention of dumping my databases as *.dump.
my question is this:
what is the equivalent to:
pg_restore --verbose --clean --no-acl --no-owner -h localhost -U myuser -d my_db db/latest.dump
using psql
so...
something along the lines of:
psql --verbose --clean --no-acl --no-owner -h localhost -U myuser -d my_db db/latest.sql
With a SQL dump you need to decide whether you want to drop target objects, when dumping the database, not when importing it.
So, you need to use:
pg_dump --clean ....
Then the SQL dump will contain the necessary DROP statements.
Another option is to run drop owned by current_user before doing the import. This however requires that everything is owned by the user doing the import (so you can't run the import as e.g. postgres)
This can be combined with running the SQL dump:
psql -U your_user -d your_db -c 'drop owned by current_user' -f your_dump.sql

Using pg_dump to take a snapshot of a database

I am trying to setup a script to take a copy of a database from one server to another.
Thanks to this post Copying PostgreSQL database to another server I have found a way to do that.
But what I need to do is change the name of the database during the copy.
I have thought about using sed and doing a simple text replace. But I am worried that this could corrupt the database.
Does any one know the proper way of doing this?
As requested here are the commands I am using
pg_dump -C -U remoteuser -h remoteServer dbname | psql -h localhost -U localadmin template1
Just restore to a different database. For pg_restore of -Fc dumps from pg_dump's custom format:
createdb newdbname
pg_restore --dbname newdbname database.dump
For SQL-format dumps not created with the -C option to pg_dump:
createdb newdbname
psql -f database_dump.sql newdbname
If you're streaming the dump from a remote host, just omit -f database_dump.sql as the dump data is coming from stdin.
You can't easily CREATE DATABASE in the same command as your restore, because you need to connect to a different DB like template1 in order to create the new DB. So in your example you might:
psql -h localhost -U localadmin template1 -c 'CREATE DATABASE newdb;'
pg_dump -U remoteuser -h remoteServer dbname | psql -h localhost -U localadmin newdb
Note the omission of the -C flag to pg_dump.
The first command is just the longhand way of writing createdb -h localhost -U localadmin newdb.
Update: If you're stuck with a pg_dump created with the -C flag you can indeed just sed the dump so long as you're extremely careful. There should only be four lines (one a comment) at the start of the file that refer to the database name. For the database name "regress" dumped with Pg 9.1's pg_dump -C:
--
-- Name: regress; Type: DATABASE; Schema: -; Owner: craig
--
CREATE DATABASE regress WITH TEMPLATE = template0 ENCODING = 'UTF8' LC_COLLATE = 'en_US.UTF-8' LC_CTYPE = 'en_US.UTF-8';
ALTER DATABASE regress OWNER TO craig;
\connect regress
This can be transformed quite safely with three (or four if you want to rewrite the comment) very specific sed commands. Do not just do a global find and replace on the database name, though.
sed \
-e 's/^CREATE DATABASE regress/CREATE DATABASE newdbname/' \
-e 's/^ALTER DATABASE regress/ALTER DATABASE newdbname/' \
-e 's/^\\connect regress/\\connect newdbname/' \
-e 's/^--Name: regress/--Name: newdbname/'
This should be a last resort; it's much better to just dump without -C.