How to move data from one database to another - postgresql

I would like to copy data from table A database A to table b database b in postgres.
I am able to use copy to write data out to a file from table A in DB A
but when I try copy into database b table B it says "ERROR: must be super user to copy to and from file"
Please help and let me know how I should data from a flatfile into a table in a database.... the db is postgres 9.x

According to the documentation:
COPY naming a file or command is only allowed to database superusers or users who are granted one of the default roles pg_read_server_files, pg_write_server_files, or pg_execute_server_program, since it allows reading or writing any file or running a program that the server has privileges to access.
However you can use pipeline to transmit data from one database to another one without using of intermediate file(s):
psql -d A -c "copy a to stdout" | psql -d B -c "copy b from stdin"
Read more about psql utility and its usage.

Related

Duplicating an entire RDS instance PostgreSQL DB to another DB within the same instance [duplicate]

Is there a simple way to create a copy of a database or schema in PostgreSQL 8.1?
I'm testing some software which does a lot of updates to a particular schema within a database, and I'd like to make a copy of it so I can run some comparisons against the original.
If it's on the same server, you just use the CREATE DATABASE command with the TEMPLATE parameter. For example:
CREATE DATABASE newdb WITH TEMPLATE olddb;
pg_dump with the --schema-only option.
If you have to copy the schema from the local database to a remote database, you may use one of the following two options.
Option A
Copy the schema from the local database to a dump file.
pg_dump -U postgres -Cs database > dump_file
Copy the dump file from the local server to the remote server.
scp localuser#localhost:dump_file remoteuser#remotehost:dump_file
Connect to the remote server.
ssh remoteuser#remotehost
Copy the schema from the dump file to the remote database.
psql -U postgres database < dump_file
Option B
Copy the schema directly from the local database to the remote database without using an intermediate file.
pg_dump -h localhost -U postgres -Cs database | psql -h remotehost -U postgres database
This blog post might prove helpful for you if you want to learn more about options for copying the database using pg_dump.
This can be done by running the following command:
CREATE DATABASE [Database to create] WITH TEMPLATE [Database to copy] OWNER [Your username];
Once filled in with your database names and your username, this will create a copy of the specified database. This will work as long as there are no other active connections to the database you wish to copy. If there are other active connections you can temporarily terminate the connections by using this command first:
SELECT pg_terminate_backend(pg_stat_activity.pid)
FROM pg_stat_activity
WHERE pg_stat_activity.datname = '[Database to copy]'
AND pid <> pg_backend_pid();
A good article that I wrote for Chartio's Data School which goes a bit more in depth on how to do this can be found here:
https://dataschool.com/learn/how-to-create-a-copy-of-a-database-in-postgresql-using-psql

PostgreSQL 13: create empty copy of database

I have a AWS RDS PostgreSQL 13 server with some databases. I have to create an empty copy of one database (empty means schema (tables, views, functions) + security (users, roles)).
Is pg_dump -s what I am looking for?
Thanks!
pg_dump -d db_name -s. You will also need to do pg_dumpall -g to get the global data e.g. roles. This will get all global data for the Postgres cluster, so you may have more then you need for the particular database.
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();

Problem restoring databse between 2 RDS instances using pg_dump and pg_restore

I'm having difficulty restoring a DB to an AWS RDS Postgresql instance. Context is that i am backing up from one RDS instance and restoring to another RDS insurance. They both have the same version of Postgresql 9.6.5.
I was able to take a dump using the following command:
./pg_dump.exe -U dbuser -W -h prod-pgsql-rds.3ft5coqxjdnq.eu-west-2.rds.amazonaws.com -d devdb > c:\tmp\backup.sql
From the resulting .sql file, I then attempted a restore to another RDS instance which is also using Postgresql 9.6.5 using below command:
./pg_restore.exe -U dbuser -d testdevdb -h dev-pgsql-rds.cym8coqx52lq.eu-west-2.rds.amazonaws.com "c:\tmp\backup.sql"
*I also tried the -f switch in the above restore command instead of the " " quotes before/after the file name
But when I try to restore it to a newly created database I get the following error:
pg_restore: [archiver] input file does not appear to be a valid archive
Can anyone help? FYI, I am using PGAdmin 4 via Windows PowerShell. I have to edit some of the values in the strings above due to data sensitivity.
pg_restore is only used for the other, non-plain-text output formats that pg_dump can output. For .sql dumps, you just use psql. See the docs on restoring from backups.
In a Unix env, you'd do psql [yourflags] < /tmp/backup.sql, but I'm unfamiliar with powershell and don't know if it supports < for input redirection; hopefully either it's present or you know the equivalent PowerShell syntax.
So I couldn't get psql or pg_restore to work so opted to import the .SQL file into via the SQL query tool in PGAmdin. This through up some errors so had to make several changes to the .SQL file and perform below:
Commented out a couple of lines that were causing errors
Elevated permissions for the user and made him the owner of for the Schema and DB properties by right-clicking on these via PGAdmin
The .sql file was making several references to the user from the source RDS DB so had to do a find and replace with a user account created for the destination RDS DB. Alternatively, I could have just created a new user on the destination DB with the same username and password as the source DB and then make him the owner in ref to step 2.

How to merge dump into database from PostgreSQL?

I'm working on the same databse schema on different machines (PostgreSQL). I would like to know, how to merge data from one machine to another. Schema has many tables (around 10). What I want to achieve?
Dump data from machine A to file A.dmp
Restore data from file A.dmp to machine B
When a record already exists in machine B, I would like to don't insert it into machine B.
I was trying dump data from machine A to simple SQL inserts commands, but when I'm trying to restore it, I am getting duplicate key errors. What is more, I would like to restore data from command line (I have to import 250 MB data), because now I'm trying to do it manually with pgAdmin.
What is the best way to do it?
I finally did it this way:
Export to dump with:
pg_dump -f dumpfile.sql --column-inserts -a -n <schema> -U <username> <dbname>
Set skip unique for all tables
CREATE OR REPLACE RULE skip_unique AS ON INSERT TO <table>
WHERE (EXISTS (SELECT 1 FROM <table> WHERE users.id = new.id))
DO INSTEAD NOTHING
Import with psql
\i <dumpfile.sql>

Can I restore just one schema from a pg_dump of the entire database?

I have backups of my postgres database - the entire database instance in a single nightly backup. Is it possible to restore just one of the database from within that backup? Or if I want to access individual databases (for migration or restoring), do I need to change my database backup scheme to do individual dumps?
You can access individual databases from a full database cluster dump in text format (pg_dumpall) by using some text processing like this:
awk '/^\\connect database_name/ {flag=1;print;next}
/^\\connect/ {flag=0}
flag { print }' \
< all_databases.sql \
> database_name.sql
This would get from pg_dumpall file everything between "\connect database_name" and next "\connect". But it is not very efficient.
But I'd recommend dumping every database separately like this:
# Dumping global data (for example roles)
pg_dumpall -g > /var/lib/pgsql/backups/globals.sql
#Dumping indidual databases in tar (uncompressed binary) format
for dbname in
`
psql -qXtc "
select datname from pg_catalog.pg_database
where datname<>'template0'" template1
`
do
pg_dump -b -F t "$dbname" > "/var/lib/pgsql/backups/$dbname.dump"
done
I'm assuming you mean "Can I restore just one database from a pg_dumpall of the entire database cluster?"
Yes, if your backup is "an archive created by pg_dump in one of the non-plain-text formats." - use the "--schema=" option to pg_restore.
On the other hand I'm not sure you're using the correct terminology here - you refer to a DB cluster as "entire database instance"; in the explanation you ask about "database" but in the title you wrote "schema", etc.
Edit: Now, after some deliberation, I believe you have a cluster backup, created with "pg_dumpall". "pg_dumpall" creates only plain-text (SQL-commands) backups. In that case it's not possible to restore only one database (or only one schema from a database).
Then yes, you need to change your backup procedure to backup individual databases using non-plain-text format (--format=custom is the recommended one).
Actually the backup procedure I use on my DB servers does just that.