July 14th, 2014 by depesz | Tags: , , , , , , , | 2 comments »
Did it help? If yes - maybe you can help me? Donate BTC to 19zPa5diT2LZqGtTi8f8bfApLn8rw9zBHx

On 10th of July, Tom Lane committed patch:

Implement IMPORT FOREIGN SCHEMA.
 
This command provides an automated way to create foreign table definitions
that match remote tables, thereby reducing tedium and chances for error.
In this patch, we provide the necessary core-server infrastructure and
implement the feature fully in the postgres_fdw foreign-data wrapper.
Other wrappers will throw a "feature not supported" error until/unless
they are updated.
 
Ronan Dunklau and Michael Paquier, additional work by me

This is pretty cool.

I assume you know about Foreign Data Wrappers. If not, quick recap – it's a way to define tables that, upon access, will query in some way some external resource. Be it text file, or another postgres database, or search twitter.

While it is great, it required definition of each table separately. In a lot of cases it makes sense. But sometimes – you want to use fdw to link another database, and you might want to add all tables from this remote database so that it would be visible in your current one.

Of course – this could have been done with shell scripts, but now we have something nicer. It will require some support from FDW drivers (wrappers), and so far, only postgres_fdw understands it, but it's there, so let's see.

In my test Pg, I create 2 databases:

create database source;
create database destination;

In source, I'll create some test tables:

$ create table t1 as select generate_series(1,10) as id;
$ create table t2 as select generate_series(1,10) + 12 as id;
$ create table t3 as select generate_series(1,10) + 45 as id;

Now, in destination database, I load the extension, and configure it:

$ create extension postgres_fdw ;
$ create server src foreign data wrapper postgres_fdw options( dbname 'source' );
$ create user mapping for depesz server src options ( user 'depesz' );

With this in place, I can create foreign tables:

$ create foreign table table_from_source (id int4) server src options (table_name 't1' );

And it will work:

$ select * from table_from_source ;
 id
----
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
(10 rows)

But now, I can do better.

First, I create some schema, so that foreign tables will not mix with local:

create schema from_source;

And now, I can:

$ import foreign schema public from server src into from_source;

After which:

$ \dE *.*
                    List of relations
   Schema    |       Name        |     Type      | Owner  
-------------+-------------------+---------------+--------
 from_source | t1                | foreign table | depesz
 from_source | t2                | foreign table | depesz
 from_source | t3                | foreign table | depesz
 public      | table_from_source | foreign table | depesz
(4 rows)

All the foreign tables from database source got “copied".

Of course this is configurable – I can limit the tables to be linked to certain list, or even use “except" to get all tables with some exceptions.

Details, as always, in the documentation.

Great stuff. Should greatly simplify creation of foreign tables – even in case of single table – as it does schema discovery, so I wouldn't need to specify all columns any more. Cool.

  1. 2 comments

  2. # Hervé
    Jul 15, 2014

    I was looking for this feature since a log time ! It’ll be very useful ! Too bad that it’s scheduled for 9.5….

  3. # Tony
    Jul 17, 2014

    just nice!!!

Leave a comment