Можно ли выполнять запросы к базе данных с помощью PostgreSQL?

StackOverflow https://stackoverflow.com/questions/46324

  •  09-06-2019
  •  | 
  •  

Вопрос

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

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

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

Это было полезно?

Решение

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

Обновление от 9.3

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

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

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

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

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

Другие советы

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

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

DBLINK выполняет запрос (обычно выберите, но это может быть любой оператор 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;

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

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

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

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

Часто задаваемые вопросы по PostgreSQL

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

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

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

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

Если кому-то нужен более подробный пример выполнения запросов между базами данных, вот пример, который очищает 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
$$
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top