2012-05-10 5 views
1

Я хотел использовать функцию timetravel (F.39. Spi, PostgreSQL 9.1 Documentation) в своем приложении, однако она, похоже, не работает должным образом для меня. При вставке строк в таблицу все работает нормально, я получаю начало и дату окончания правильно, но когда я пытаюсь обновить эти строки, postgres дает мне ошибку в нарушении ограничения PRIMARY KEY. Он пытается вставить кортеж с тем же основным идентификатором, что и предыдущий набор ...Timetravel в 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' 

Я получаю error- описано ранее.

Схема состояний

-- 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

+2

Покажите нам TABLE CREATE и операторы UPDATE выполняющиеся –

+0

Вы можете попробовать консультации с [пример путешествия во времени] (https://github.com/postgres/postgres/blob/master/contrib/spi/timetravel.example) для подсказок. [timetravel docs] (http://www.postgresql.org/docs/9.1/static/contrib-spi.html) для тех, кто их не видел. И, наконец, [обсуждение решения тех же проблем без использования временных путешествий] (http://stackoverflow.com/questions/125877/versioning-database-persisted-objects-how-would-you) –

+0

Опубликовать схему состояний и выборочных записей в состояниях. – tuxuday

ответ

1

Времени travel конвертирует UPDATE в UPDATE из stop_date старой записи и INSERT нового с измененными данными плюс бесконечность stop_date. Из-за pk_cities у вас не может быть более одной записи для city_id. Триггеры времени не позволяют вам нарушить это требование.

Вы не можете использовать это:

CONSTRAINT pk_cities PRIMARY KEY (city_id) 

Вы должны использовать этот

CONSTRAINT pk_cities PRIMARY KEY (city_id, stop_date) 
+0

Спасибо, он работает. – Borys

Смежные вопросы