Проблемы postgresql с модулем postgres_fdw

Я пытаюсь с помощью инструмента PostgreSQL Maestro ссылаться на внешний ключ, поступающий из «локальной» БД, на другой первичный ключ внутри другой БД (фактически, они оба находятся на одном удаленном компьютере). Я слышал о модуле postgres_fdw для создания сторонней таблицы, которая действует как копия таблицы внутри удаленной БД, но когда я пытаюсь выполнить свой запрос, у меня появляется эта ошибка:

«Ошибка SQL: ОШИБКА: указанное отношение« foreign_olo »не является таблицей».

Это мой код sql:

CREATE TABLE edb.olo_config (  
primary_key       integer NOT NULL PRIMARY KEY,
puntamento        varchar,
mail_contatto_to  varchar,
mail_contatto_cc  varchar,
/* Foreign keys */
CONSTRAINT olo_code
  FOREIGN KEY (olo_code)
  REFERENCES edb.foreign_olo(codice_operatore)
) WITH (
  OIDS = FALSE
);

foreign_olo - моя внешняя таблица, созданная с помощью postgres_fdw. Я попытался зафиксировать INSERT или простой SELECT в таблице foreign_olo, и все прошло хорошо, поэтому я не могу понять, почему для случая внешнего ключа он не может быть распознан как таблица. Спасибо всем, кто протянул мне руку помощи!


person JinLemon    schedule 27.04.2016    source источник


Ответы (1)


Ограничение внешнего ключа состоит из двух частей:

  • INSERT (или UPDATE поля FK) в дочерней таблице должен проверять, существует ли родительская запись.
  • DELETE (или UPDATE поля PK) в родительской таблице должен проверять, что дочерняя запись не существует.

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

Вы можете относительно легко реализовать первую проверку с помощью триггера:

CREATE FUNCTION edb.olo_config_fk_trg() RETURNS TRIGGER AS
$$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM edb.foreign_olo
    WHERE codice_operatore = new.olo_code
    FOR KEY SHARE
  )
  THEN
    RAISE foreign_key_violation
      USING MESSAGE = 'edb.foreign_olo.codice_operatore="' || new.olo_code || '" not found';
  END IF;
  RETURN NULL;
END
$$
LANGUAGE plpgsql;

CREATE TRIGGER olo_config_fk_trg
AFTER INSERT OR UPDATE OF olo_code ON edb.olo_config
FOR EACH ROW EXECUTE PROCEDURE edb.olo_config_fk_trg();

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

person Nick Barnes    schedule 28.04.2016