Ошибки при создании триггера ограничения

Позвольте мне начать с того, что я администратор Linux/Unix. При этом мой менеджер поручил мне перенести старые базы данных PostgreSQL на сервер RedHat под управлением 8.4.20. Мне удалось перенести 7.2.1 db, но у меня возникли проблемы с перемещением 7.4.20 db.

Я использую pg_dump –c filename и psql < filename. Для проблемной базы данных все работает, пока я не доберусь до оператора CREATE CONSTRAINT TRIGGER. Если я запускаю его так, как он есть в файле, я получаю:

ВНИМАНИЕ: игнорирование неполной группы триггеров для ограничения "" данные FOREIGN KEY(ups) REFERENCES upsinfo(ups) DETAIL: найден триггер DELETE ссылочной таблицы. СОЗДАТЬ ТРИГГЕР

Если я запускаю set schema 'pg_catalog';, я получаю:

ОШИБКА: отношение "upsinfo" не существует

Используемые таблицы (я думаю):

CREATE TABLE upsinfo (
    ups text NOT NULL,
    ipaddr inet,
    rcomm text,
    wcomm text,
    reachable boolean,
    managed boolean,
    comments text,
    region text
);

CREATE TABLE data (
    date timestamp with time zone,
    ups text,
    mib text,
    value text
);

Оператор триггера проблемы триггера:

CREATE CONSTRAINT TRIGGER "<unnamed>"
    AFTER DELETE ON upsinfo
    FROM data
    NOT DEFERRABLE INITIALLY IMMEDIATE
    FOR EACH ROW
    EXECUTE PROCEDURE "RI_FKey_cascade_del"('<unnamed>', 'data', 'upsinfo', 'UNSPECIFIED', 'ups', 'ups');

Я знаю, что функция RI_FKey_cascade_del определяется по-разному в разных версиях pg_catalog. Обратите внимание, что для параметра search_path установлено значение «public, pg_catalog», поэтому я также не понимаю, почему я должен устанавливать схему.

Опять же, я не настоящий администратор баз данных PostgreSQL, поэтому постарайтесь быть добрее.


person Jesse Carroll    schedule 17.08.2016    source источник


Ответы (2)


Уф, это действительно старые версии postgres, включая версию, до которой вы обновляетесь (версия 8.4 была выпущена в 2009 году, а поддержка закончилась в 2014 году).

Короткий ответ заключается в том, что пока upsinfo и data создаются и заполняются, у вас, вероятно, все в порядке и все готово. Но одно из ваших отношений внешнего ключа нарушено.

Длинный ответ: давайте посмотрим, смогу ли я объяснить, что происходит (или, по крайней мере, что я думаю, что происходит).

Я предполагаю, что исходное определение таблицы data включало что-то вроде FOREIGN KEY (ups) REFERENCES upsinfo (ups) ON DELETE CASCADE. Это приводит к тому, что postgres автоматически создает некоторые триггерные ограничения: 1- каждый раз, когда появляется новая строка для data, убедитесь, что ее столбец ups соответствует существующей строке в upsinfo, и 2- каждый раз, когда вы удаляете строку из upsinfo, удаляйте соответствующие строки в data на основе совпадающего значения ups.

Это (не очень информативное) сообщение об ошибке может появиться, когда отношение внешнего ключа не работает. Чтобы внешний ключ имел смысл, ссылочное значение должно быть уникальным — в upsinfo должна быть только одна строка для каждого отдельного значения ups. Чтобы postgres знал об этом, должен быть уникальный индекс или первичный ключ на upsinfo.ups.

В этом случае одна из нескольких вещей может сломать его:

  1. В upsinfo.ups нет первичного ключа или уникального индекса (postgres не должен был разрешать внешний ключ, но может иметь в очень старых версиях)
  2. Раньше был уникальный индекс, но он не обеспечивал должным образом уникальность, поэтому он не был успешно импортирован (ошибка, опять же, вероятно, из очень старой версии)

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

ALTER TABLE data
  ADD FOREIGN KEY (ups) REFERENCES upsinfo (ups) ON DELETE CASCADE;

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

Надеюсь, это поможет, и удачи!

person jmelesky    schedule 17.08.2016

Кажется, это часть ON DELETE CONSTRAINT. На вашем месте я бы удалил все такие операторы и заменил их правильным определением ограничения в целевой таблице.

Определение таблицы должно выглядеть следующим образом:

CREATE TABLE bookings (
    boo_id serial NOT NULL,
    boo_hotelid character varying NOT NULL,
    boo_roomid integer NOT NULL,
    CONSTRAINT pk_bookings
        PRIMARY KEY (boo_id),
    CONSTRAINT fk_bookings_boo_roomid 
        FOREIGN KEY (boo_roomid)
        REFERENCES rooms (roo_id) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE CASCADE
) WITHOUT OIDS;

И эта часть — то, что внутри создаст триггер:

    CONSTRAINT fk_bookings_boo_roomid 
        FOREIGN KEY (boo_roomid)
        REFERENCES rooms (roo_id) MATCH SIMPLE
        ON UPDATE CASCADE ON DELETE CASCADE

Но, если честно, у меня нет понимания за обновление до неподдерживаемой версии. Вы знаете, что Postgres сейчас версии 9.5, верно?

person Boris Schegolev    schedule 17.08.2016
comment
Спасибо за помощь. (И за мягкость.) Это типичная история: никто не поддерживает программное обеспечение в течение многих лет, а затем внезапно все заводится. Я попрошу (скорее умоляю) обновить версию Postgres на новом сервере. - person Jesse Carroll; 18.08.2016