Cross Database Query in PostgreSQL
I have been using Postgres for the last few years and recently came across the use case of cross-database query. I am sharing the same and if you have the same kind of requirement you might it interesting.
Before going into more details, let's go through a few basic differences between MySQL and PostgreSQL:
A schema for both the DBMSs doesn't mean the same thing.
MySQL:
- Synonymous to the database.
- Allows across database queries. For example,
- SELECT * FROM db1.table1 tb1 inner join db2.table2 tb2 on tb1.column1 = tb2.column
PostgreSQL:
- A namespace within the database. By default, a database contains three schemas namely information_schema, pg_catalog, and public. In the public schema, all tables and views created by a user reside.
- Doesn't allow across database queries out of the box. Foreign data wrapper does the same job.
It provides a way to allow across database queries.
NOTE: The following set of commands have experimented on docker containers. It might differ for other PostgreSQL service providers such as RDS on AWS.
PostgreSQL provides across database queries with the help of the extension "postgres_fdw".
This extension is PostgreSQL to PostgreSQL connector, where databases can reside on the same host of different hosts.
We will use the term Current Database(where you will need tables from another database) to refer current database and Remote Database to refer another database to which we create link.
Use the following steps to enable the same:
- Activate the Wrapper
- Log into the postgres docker and run following commands(docker exec -it <pg_docker> bash)
- \c <Current Database>;
- CREATE EXTENSION postgres_fdw;
- GRANT CONNECT ON DATABASE <Remote Database> TO <CURRENT_DB_USER>;
- GRANT USAGE ON SCHEMA public TO <CURRENT_DB_USER>;
- GRANT SELECT ON ALL TABLES IN SCHEMA public TO <CURRENT_DB_USER>;
- ALTER DEFAULT PRIVILEDGES FOR ROLE <CURRENT_DB_USER> IN SCHEMA public GRANT SELECT ON TABLES TO <CURRENT_DB_USER>;
- Create Server Connection:
- Now, connect to current database :
- CREATE SERVER <remote_server_connection_name>
- FOREIGN DATA WRAPPER postgres_fdw
- OPTIONS(host '<remote_host_address>', dbname '<remote_database_name>', port '<port_number>');
- Create User Mapping:
- With the same database connection as in step 2, run following commands:
- OPTIONS(user '<remote_database_user>', password '<remote_database_password>');
- CREATE USER MAPPING FOR <remote_server_connection_name>
- OPTIONS(user '"root-pg"', password '<remote_database_password>');
- Import Data
- Now that remote server connection has been created and user mappings are also done, its time to import remote schema. Though all tables can be imported, it should be limited to required tables only.
- IMPORT FOREIGN SCHEMA public
- LIMIT TO (table1, table2, table3)
- FROM SERVER <remote_server_connection_name> INTO public;
- Verify Setup
- The following two queries can be run to find out remote server connection and availabe tables from remote database.
- -------------------------------------------------------------------------------
- --------------------------------------------------------------
- <remote_server_connection_name> | 12321 | 23432 | | | |
- {host=<host_address>, dbname=<db_name>, port=<port_number>}
- SELECT * FROM pg_foreign_table;
- ftrelid | ftserver | ftoption
- ------------------------------------------------------------------------
- 12343 | 12345 | {schema_name=public, table)name=<remote_table_name>}
- Query
- Now, that remote tables are imported and availbe in the current database, any query can be run on the same. For example,
- FROM <remote_table_name>;
psql -U root-pgpsql -h <current_db_host> -d <current_database> -p <port> -U <current_db_user> -W
CREATE USER MAPPING FOR <remote_server_connection_name>
SELECT * FROM pg_foreing_server;
srvname | srvowner | srvfdw | srvtype | srvversion | srcacl | srvoptions
SELECT *Note:- Please write comment for any queries.
Comments
Post a Comment