Возможно ли выполнять кросс-запросы к базам данных с PostgreSQL? - PullRequest
120 голосов
/ 05 сентября 2008

Я собираюсь угадать, что ответ «нет» на основании приведенного ниже сообщения об ошибке (и этот результат Google ), но есть ли способ выполнить запрос к базе данных с использованием PostgreSQL?

databaseA=# select * from databaseB.public.someTableName;
ERROR:  cross-database references are not implemented:
 "databaseB.public.someTableName"

Я работаю с некоторыми данными, которые распределены по двум базам данных, хотя данные действительно распределяются между ними (столбцы идентификаторов пользователей в одной базе данных взяты из таблицы users в другой базе данных). Я понятия не имею, почему это две отдельные базы данных вместо схемы, но c'est la vie ...

Ответы [ 7 ]

94 голосов
/ 05 сентября 2008

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

Дополнение от 9.3

Теперь вы можете использовать новую postgres_fdw (оболочку внешних данных) для подключения к таблицам в любой базе данных Postgres - локальной или удаленной.

Обратите внимание, что существуют сторонние оболочки данных для других популярных источников данных . В настоящее время только postgres_fdw и file_fdw являются частью официального дистрибутива Postgres.

Оригинальный ответ до 9.3

Эта функциональность не является частью установки PostgreSQL по умолчанию, но вы можете добавить ее. Она называется dblink.

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

20 голосов
/ 05 сентября 2008

Я сталкивался с этим до того, как пришел к тому же выводу о кросс-запросах к базе данных, что и вы. В итоге я использовал схемы для разделения табличного пространства таким образом, чтобы я мог сохранять таблицы сгруппированными, но при этом запрашивать их все.

16 голосов
/ 21 ноября 2014

dblink () - выполняет запрос в удаленной базе данных

dblink выполняет запрос (обычно это SELECT, но это может быть любой SQL оператор, который возвращает строки) в удаленной базе данных.

Когда заданы два текстовых аргумента, первый из них сначала выглядит как имя постоянного соединения; если найдено, команда выполняется эта связь. Если не найдено, первый аргумент обрабатывается как Строка информации о соединении как для dblink_connect, так и указанная соединение устанавливается только на время выполнения этой команды.

один из хороших примеров:

SELECT * 
FROM   table1 tb1 
LEFT   JOIN (
   SELECT *
   FROM   dblink('dbname=db2','SELECT id, code FROM table2')
   AS     tb2(id int, code text);
) AS tb2 ON tb2.column = tb1.column;

Примечание: я даю эту информацию для дальнейшего использования. Refrence

10 голосов
/ 07 мая 2010

Просто чтобы добавить немного больше информации.

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

contrib / dblink разрешает запросы между базами данных с использованием вызовов функций. Конечно, клиент также может одновременно устанавливать соединения с различными базами данных и объединять результаты на стороне клиента.

FAQ по PostgreSQL

5 голосов
/ 22 сентября 2008

Да, вы можете использовать DBlink (только postgresql) и DBI-Link (разрешает сторонние перекрестные запросы к базам данных) и TDS_LInk, который позволяет выполнять запросы к серверу MS SQL.

Я с большим успехом использовал DB-Link и TDS-link.

2 голосов
/ 12 сентября 2008

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

Это можно сделать с помощью простых триггеров вставки, которые в свою очередь вызывают dblink для обновления другой копии. Есть также полноценные варианты репликации (например, Slony), но это не по теме.

0 голосов
/ 12 апреля 2019

Если кому-то нужен более сложный пример того, как выполнять запросы между базами данных, вот пример, который очищает таблицу databasechangeloglock в каждой базе данных, в которой она есть:

CREATE EXTENSION IF NOT EXISTS dblink;

DO 
$$
DECLARE database_name TEXT;
DECLARE conn_template TEXT;
DECLARE conn_string TEXT;
DECLARE table_exists Boolean;
BEGIN
    conn_template = 'user=myuser password=mypass dbname=';

    FOR database_name IN
        SELECT datname FROM pg_database
        WHERE datistemplate = false
    LOOP
        conn_string = conn_template || database_name;

        table_exists = (select table_exists_ from dblink(conn_string, '(select Count(*) > 0 from information_schema.tables where table_name = ''databasechangeloglock'')') as (table_exists_ Boolean));
        IF table_exists THEN
            perform dblink_exec(conn_string, 'delete from databasechangeloglock');
        END IF;     
    END LOOP;

END
$$
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...