GIS-LAB

Географические информационные системы и дистанционное зондирование

PostgreSQL: удаленные источники данных средствами dblink

Дежин Александр, 19.08.2010

Недавно в этом блоге вы могли наблюдать заметку о публикации данных в формате PostGIS, в том числе и данных OSM. Конечно, это не отменяет публикуемых shape-файлов, однако скачивать их при каждом обновлении может быть не всегда удобно, особенно если вам нужен какой-либо специфический срез этих данных. Поэтому хотелось бы рассказать о одном, как мне кажется, довольно интересном способе получения этих данных встроенными средствами  PostgreSQL и PostGIS.

Самый очевидный способ, получить копию таблицы – это воспользоваться pg_dump -t <имя_таблицы>, а затем pg_restore и зарегистрировать колонку геометрий – однако это скучно и не интересно, да и фильтры там наложить негде.

Для PostgreSQL есть расширение dblink, которое позволяет выполнять запросы к удаленным базам данных непосредственно из SQL, не прибегая к помощи внешних скриптов.

Чтобы включить это расширение нужно посмотреть папку, в которую у вас были установлены расширения (точный путь может зависеть от дистрибутива), и выполнить dblink.sql из этой папки на вашей БД. Например, так:

psql -U <имя_пользователя> -h <хост_бд> <имя_бд> < /usr/share/postgresql-8.4/contrib/dblink.sql

То есть процедура установки, очень похожа на установку PostGIS. После этого, можно напрямую обращаться к удаленным базам из своих SQL-скриптов, например, так:

SELECT *
FROM dblink('dbname=osm host=gis-lab.info user=guest password=guest',
  'SELECT osm_id, waterway, name, way FROM osm_line WHERE waterway IN (''river'', ''stream'')'
) AS rivers(osm_id int, tag varchar(50), name varchar(200), way geometry);

Где:

  • 'dbname=osm host=gis-lab.info user=guest password=guest' –  это строка подключения к удаленной базе
  • 'SELECT osm_id, waterway, name, way FROM osm_line WHERE ...' –  запрос, который вы хотите выполнить (escape-последовательность для одинарных кавычек – '' )
  • rivers(osm_id int, tag varchar(50), name varchar(200), way geometry) – псевдоним в текущем запросе и описание полей с их типами

При необходимости выбрать данные по охвату, можно поступить например так:

SELECT *
FROM dblink('dbname=osm host=gis-lab.info user=guest password=guest',
  'SELECT osm_id, name, way FROM osm_point WHERE place IN (''city'',''town'')
    AND way && ST_SetSRID(ST_MakeBox2D(ST_Point(37.32, 56.53), ST_Point(41.20, 58.96)), 4326)'
) AS rivers(osm_id int, name varchar(50), geom geometry);

Где,  ST_SetSRID(ST_MakeBox2D(ST_Point(37.32, 56.53), ST_Point(41.20, 58.96)), 4326) – охват ярославской области, а && – оператор пересечения. Таким образом можно выбрать все крупные населенный пункты ярославской области, обозначенные как place=city|town.

Если по каким-то причинам вам не удобно указывать строку соединения каждый раз, то можно воспользоваться dblink_connect для того чтобы создать подключение и в дальнейшем его использовать.

Комментарии (6) к статье “PostgreSQL: удаленные источники данных средствами dblink”

  1. _DR_ says:

    Спасибо за информацию, будем знать. Как я понял данная процедура полезна при создании скриптов. Но таким же образом ведь можно подключаться и работать с базами средствами самого языка, использующего данные SQL скрипты?

    • Дежин Александр says:

      Конечно всегда можно скопировать данные в рабочую базу тем или иным способом, но иногда никакого языка то и нет – просто SQL-скрипты запускаются через psql. В этой ситуации такой подход может быть несколько удобней. По крайней мере мне dblink пригодился именно в такой ситуации.

      • _DR_ says:

        Может я что-то не понимаю, но почему бы просто не писать psql -h gis-lab.info -d osm -f smth.sql. ?ли dblink позволяет делать запросы (например, содержащиеся в файле smth.sql) к другим базам, расположенным на других хостах, нежели, как -h gis-lab.info -d osm?

        • Дежин Александр says:

          Да, в этом и фишка, – хост и база могут быть любыми независимо от текущей базы и хоста.

  2. […] Довольно распространена ситуация, когда данные не консолидированы, содержатся в независимых хранилищах или появляются в результате выполнения запроса (процесса). В такой ситуации можно применить агрегацию. Например, в п. 1а включить БД PostgreSQL с применением расширения dblink. […]

Оставтьте комментарий к Дежин Александр


(Геокруг)

Если Вы обнаружили на сайте ошибку, выберите фрагмент текста и нажмите Ctrl+Enter