PostgreSQL 9.3devel - Nova extensão "postgres_fdw"
Autor: Fabrízio de Royes Mello | Publicado: 2013-02-21T16:37:00-03:00

Apartir da release 9.1 o PostgreSQL adicionou suporte a foreign tables, viabilizando assim uma forma simples de gerenciar fontes de dados externas dentro do PostgreSQL.

Através dessa infraestrutura é possível a implementação dos FDW (Foreign Data Wrapper), que são uma espécie de driver para acessar uma fonte de dados externa. 

Já existem diversos FDW implementados que permitem acessar outros bancos de dados (oracle, mysql, etc), arquivos (texto, csv, etc), bases NoSQL (mongodb, couchdb, redis, etc) e outras fontes de dados diferentes, tais como: twitter, ldap, www, etc.

Hoje foi commitado no git do PostgreSQL um FDW específico para acessar bases PostgreSQL, chamado "postgres_fdw", então vou demonstrar como instalar/configurar de uma forma muito simples.


1) Instalar o "postgres_fdw" apartir do git

Nesse exemplo vou mostrar como instalar/compilar o PostgreSQL apartir do git oficial, mas se vc tiver uma conta no github pode usar tb o nosso clone do repositório oficial.

git clone git://git.postgresql.org/git/postgresql.git
cd postgresql
./configure --prefix=$HOME/pgsql
make
make install
cd contrib/postgres_fdw
make
make install


2) Inicializar um novo cluster e colocar o PostgreSQL para executar

$ cd $HOME/pgsql
$ mkdir data
$ chmod 700 data
$ ./bin/initdb -D data 
$ ./bin/pg_ctl -D data -l startup.log start


3) Criar bases e tabela para testes

$ cd $HOME/pgsql
$ ./bin/createdb bd1
$ ./bin/createdb bd2
$ ./bin/psql bd2 -c "create table foo(bar integer);"
$ ./bin/psql bd2 -c "insert into foo(bar) select * from generate_series(1, 10);"

Para explicar, criamos 2 (duas) bases de dados "bd1" e "bd2", e no "bd2" criamos uma tabela chamada "foo" a qual iremos acessar apartir do "bd1" criando uma foreign table como explicarei em seguida.


4) Criar a extensão "postgres_fdw" no "bd1"

$ ./bin/psql bd1
psql (9.3devel)
Type "help" for help.

bd1=# CREATE EXTENSION postgres_fdw ;
CREATE EXTENSION

bd1=# \dx
                               List of installed extensions
     Name     | Version |   Schema   |                    Description                     
--------------+---------+------------+----------------------------------------------------
 plpgsql      | 1.0     | pg_catalog | PL/pgSQL procedural language
 postgres_fdw | 1.0     | public     | foreign-data wrapper for remote PostgreSQL servers
(2 rows)


5) Criar conexão com "bd2" no "bd1"

bd1=# CREATE SERVER conexao_bd2 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (dbname 'bd2');
CREATE SERVER

bd1=# \des+
                                              List of foreign servers
    Name     |  Owner   | Foreign-data wrapper | Access privileges | Type | Version |  FDW Options   | Description 
-------------+----------+----------------------+-------------------+------+---------+----------------+-------------
 conexao_bd2 | fabrizio | postgres_fdw         |                   |      |         | (dbname 'bd2') | 
(1 row)

bd1=# CREATE USER MAPPING FOR current_user SERVER conexao_bd2 ;
CREATE USER MAPPING

bd1=# \deu+
         List of user mappings
   Server    | User name | FDW Options 
-------------+-----------+-------------
 conexao_bd2 | fabrizio  | 
(1 row)



6) Acessar a tabela "foo" do "bd2" apartir do "bd1"

bd1=# CREATE FOREIGN TABLE foo (bar integer) SERVER conexao_bd2 ;
CREATE FOREIGN TABLE

bd1=# \d
            List of relations
 Schema | Name |     Type      |  Owner   
--------+------+---------------+----------
 public | foo  | foreign table | fabrizio
(1 row)

bd1=# SELECT * FROM foo;
 bar 
-----
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
(10 rows)


Considerações

Segundo a própria documentação oficial, o "postgres_fdw" é uma alternativa mais robusta em relação ao antigo "dblink" pois nos oferece uma sintaxe mais padronizada e simplificada para acessar tabelas remotas, inclusive com melhor desempenho em muitos casos. 

E pelo que pude acompanhar do seu desenvolvimento, parece que essa FDW deve servir como modelo para o desenvolvimento de outras FDW para acessar outras bases de dados relacionais.

De uma forma muito simples é possível acessar tabelas de outra base de dados PostgreSQL, e o mesmo ocorre com outras fontes de dados, mas por enquanto apenas para leitura (SELECT), entretanto já está em revisão um patch para permitir escrita (INSERT/UPDATE/DELETE) em foreign tables, vamos aguardar.