Query tables from multiple servers with postgreSQL - postgresql

I have several databases on the different PostgreSQL servers with the tables with the same columns in it
(installs_1, installs_2 and installs_3)
installs(country varchar, date datetime,paid boolean, installs int)
I want to write a function that a user could use to query across all these databases at once, how can I do it?
my query is:select country,count(*) from t1,t2

A PostgreSQL extension that offer this feature is the postgres_fdw. Here is an example of how to set it up:
First you create the extension:
CREATE EXTENSION postgres_fdw
After that you create a server pointing to the foreign postgres server
CREATE SERVER remote_postgres
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (dbname 'mydb', host 'remoteserver', port '5432');
Then an user mapping, so that an user in your current database may access the foreign database:
CREATE USER MAPPING FOR local_user
SERVER remote_postgres
OPTIONS (user 'foreign_user', password 'secret');
And finally you create a foreign table to link both tables
CREATE FOREIGN TABLE foreign_table_test
(id INT, description TEXT)
SERVER remote_postgres
OPTIONS (schema_name 'public', table_name 'table_test');
Once your table is created you can query it like you'd query a normal/local table:
SELECT * FROM foreign_table_test
Further reading:
A closer look into postgres_fdw
postgres_fdw documentation examples

Related

How to update table records in a database based on a table with the same table in another database?

Let's assume that I have db1 and db2, two databases. I would like to perform a command of the like of
update db2.person p2
set p2.name = p1.name
from db1.person p1
where p1.id = p2.id;
This is possible in MySQL without any problems. I have great difficulty achieving it in PostgreSQL.
What I have tried:
create extension postgres_fdw;
create server theservername
foreign data wrapper postgres_fdw
options(host 'localhost', dbname 'thedbname', port '5432');
create user mapping for theuser
server theservername
options(user 'theusername', password 'thepassword');
And here I'm stuck, I don't know how to proceed. None of these troubles exist in MySQL. How can I overcome them in PostgreSQL?
Steps are following:
Step - 1: Create Extension
create extension postgres_fdw;
Step - 2: Create Server
create server theservername
foreign data wrapper postgres_fdw
options(host 'localhost', dbname 'thedbname', port '5432');
Step - 3: Create Foreign User Mapping for the server
create user mapping for theuser
server theservername
options(user 'theusername', password 'thepassword');
Step - 4: Create Foreign Table with same structure as in another DB
create foreign table "schema_name"."local_table_name"
(
id_ int;
...
-- field list same as foreign table in other db
)
server theservername
options(SCHEMA_NAME 'foreign_schema', TABLE_NAME 'foreign_name');
Now you can use local_table_name in your query just as local table. It will do all operations on remote db.
Your update query can be written like below:
update local_table_name p2
set name = p1.name
from person p1
where p1.id = p2.id;

Logging records in a postgresql database

I am having trouble thinking of a way to copy three fields out of a database into and append them to another table along with the current date. Basically what I want to do is:
DB-A: ID (N9), Name (C69), Phone (N15) {and a list of other fields I dont care about}
DB-B: Date (Todays date/time), Nane, Address, Phone (as above)
Would be great is this was a trigger in the DB on add or update of DB-A.
Greg
Quick and dirty using postgres_fdw
CREATE EXTENSION IF NOT EXISTS postgres_fdw ;
CREATE SERVER extern_server FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'foreignserver.co.uk', port '5432', dbname 'mydb');
CREATE USER MAPPING FOR myuser SERVER extern_server OPTIONS (user 'anotheruser');
-- Creating a foreign table based on table t1 at the server described above
CREATE FOREIGN TABLE foreign_t1 (
dba INT,
name VARCHAR(9),
phone VARCHAR(15)
)
SERVER extern_server OPTIONS (schema_name 'public', table_name 't1');
--Inserting data to a new table + date
INSERT INTO t2 SELECT dba,name,phone,CURRENT_DATE FROM foreign_t1;
-- Or just retrieving what you need placing the current date as a column
SELECT dba,name,phone,CURRENT_DATE FROM foreign_t1;

Can I query foreign servers without creating foreign tables?

I know that dblink can be queried directly like:
select * from dblink('kenyon_dblink','select * from test') as t1 (id integer,name varchar);
I wonder if I can query foreign servers without creating foreign tables, since my query strings are generated dynamically.
Yes you can, just open a dblink connection in the same session with dblink_connect() (named or unnamed).
Example:
Is there any shortcut for using dblink in Postgres?
Example with dynamic SQL:
Syntax error in function using dblink to replicate new data
This works for connections between PostgreSQL DBs, not for other RDBMS. Per documentation:
dblink is a module that supports connections to other PostgreSQL
databases.

Problems while Using postgres_fdw

I m getting some problem while using postgres_fdw.
CREATE SERVER foreign_server
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '192.162.0.1', port '5432', dbname 'Test');
CREATE USER MAPPING FOR postgres
SERVER foreign_server
OPTIONS (user 'foreign_user', password 'password');
CREATE FOREIGN TABLE foreign_table (
id serial NOT NULL,
data text)SERVER foreign_server
OPTIONS (schema_name 'public', table_name 'employee');
select * from employee where user ='foreign_user'
Now I can see entries are made to pg_foreign_data_wrapper, pg_foreign_server and pg_foreign_table tables.
But how do I access employee table of remote system.
I mean select * from employee where user ='foreign_user' doesn't give any result. Though it has data in Employee table of remote system.
Any idea please?
But How do I access employee table of remote system.
You just need to access the foreign table, say "SELECT * FROM foreign_table;".
The procedure seems fine, but your foreign table doesn't have a column named "user", so your query must cause an error.
It would be better to show what has happened actually. Showing actual query and error messages helps us understand where the problem is.

Create a foreign table pointing to a view in Postgres

Is it possible to create a foreign table, using Postgres Foreign Data Wrapper, that points to a view instead of a table?
Yes, it is possible!
The following query worked perfectly:
CREATE FOREIGN TABLE facts(name character varying(255))
SERVER my_server
OPTIONS (table_name 'facts');
Where facts is a view in my_server instead of a table.
Recently I had to do the same thing and here are the steps that worked for me. All these commands are run on the local postgreSQL DB.
CREATE EXTENSION postgres_fdw;
CREATE SERVER remote_server_name
FOREIGN DATA WRAPPER postgres_fdw
OPTIONS (host '10.10.10.10', port '5432', dbname 'remote_db_name');
CREATE USER MAPPING FOR local_user_name
SERVER remote_server_name
OPTIONS (user 'remote_user', password 'remote_password');
CREATE FOREIGN TABLE local_table_name (
id NUMERIC NOT NULL,
row TEXT,
another_row INTEGER,
whatever_row TEXT
)
SERVER remote_server_name
OPTIONS (schema_name 'public', table_name 'remote_table_name');
I have the same question.
In pgadmin4 for postgresql-11, if use GUI Command: Create -> Foreign Table...
on table, it works; but on view, it does't works, you will get a empty table.
for view, i use this code, it works:
IMPORT FOREIGN SCHEMA remote_schema_name
LIMIT TO (remote_view_name)
FROM SERVER remote_host_map_name INTO local_shema_name;
The reason is, for table, pgadmin4 can create columns same as remote table in constract SQL statement, but for view, it create no columns in constract SQL statement.