Timetravel в postgres - нарушение ограничения PRIMARY KEY
Я хотел использовать функцию timetravel (F.39. Spi, PostgreSQL 9.1 Documentation) в моем приложении, однако, похоже, она не работает для меня должным образом. При вставке строк в таблицу все работает отлично, я правильно получаю дату начала и окончания, но когда я пытаюсь обновить эти строки, postgres выдает ошибку об нарушении ограничения PRIMARY KEY. Он пытается вставить кортеж с тем же основным идентификатором, что и предыдущий кортеж...
Безумно удалять ограничения первичного ключа из всех таблиц в базе данных, но мне нужна эта функциональность. Так, может быть, у вас есть опыт работы с timetravel?
Любая помощь будет оценена. Заранее спасибо.
DDL:
CREATE TABLE cities
(
city_id serial NOT NULL,
state_id integer,
name character varying(80) NOT NULL,
start_date abstime,
stop_date abstime,
CONSTRAINT pk_cities PRIMARY KEY (city_id ),
CONSTRAINT fk_cities_states FOREIGN KEY (state_id)
REFERENCES states (state_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
-- Trigger: time_travel on cities
-- DROP TRIGGER time_travel ON cities;
CREATE TRIGGER time_travel
BEFORE INSERT OR UPDATE OR DELETE
ON cities
FOR EACH ROW
EXECUTE PROCEDURE timetravel('start_date', 'stop_date');
ДАННОЕ ЗАЯВЛЕНИЕ:
INSERT INTO cities(
state_id, name)
VALUES (20,'Paris');
и это нормально. Я получаю start_date и stop_date. Но по:
UPDATE cities SET name='Rome' WHERE name='Paris'
Я получаю ошибку, описанную ранее.
Схема состояний
-- Table: states
-- DROP TABLE states;
CREATE TABLE states
(
state_id serial NOT NULL, -- unikatowy numer wojewodztwa
country_id integer, -- identyfikator panstwa, w ktorym znajduje sie wojewodztwo
name character varying(50), -- nazwa wojewodztwa
CONSTRAINT pk_states PRIMARY KEY (state_id ),
CONSTRAINT uq_states_state_id UNIQUE (state_id )
)
WITH (
OIDS=FALSE
);
К сожалению, как новый пользователь я не могу размещать изображения здесь. Вы можете увидеть их там:
Пример данных из таблицы городов: korpusvictifrew.cba.pl/postgres_cities.png
Пример данных из табличных состояний: korpusvictifrew.cba.pl/states_data.png
1 ответ
Путешествие во времени преобразует UPDATE в UPDATE старой записи stop_date и INSERT новой записи с измененными данными плюс бесконечность stop_date. Вы не можете иметь более одной записи для city_id из-за pk_cities. Триггеры путешествия во времени не позволяют вам нарушить это требование.
Вы не можете использовать это:
CONSTRAINT pk_cities PRIMARY KEY (city_id )
Вы должны использовать это
CONSTRAINT pk_cities PRIMARY KEY (city_id, stop_date)