Отличный (и, надо сказать, давно ожидаемый) патч от Tom Lane:
Теперь pg_dump --data-only пытается упорядочить дампы таблиц таким образом,Что это означает в действительности?
что таблицы, на которые ссылаются вторичные ключи, выгружаются раньше таблиц,
содержащих эти ключи. Это помогает обходить сбои, возникающие при загрузке
данных,которые ссылаются на ещё не загруженные данные. Когда такое упорядочивание
не возможно, в случае циклических зависимостей или ссылок на самих себя, выводит
NOTICE для предупреждения об этом пользователя.
Начнём с простого допущения - этот патч затрагивает выгрузку только данных (--data-only). Так что, если вы это не используете, то вам оно ничем не поможет. Простите.
Но, если используете, и у вас "пропатченая" версия postgres, вот что произойдёт:
Во первых, создадим кое-какие таблицы:
# create table b (id serial primary key);И добавим данных:
NOTICE: CREATE TABLE will create implicit sequence "b_id_seq" for serial column "b.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "b_pkey" for table "b"
CREATE TABLE
# create table a (id serial primary key, b_id int4 references b (id));
NOTICE: CREATE TABLE will create implicit sequence "a_id_seq" for serial column "a.id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "a_pkey" for table "a"
CREATE TABLE
# insert into b (id) values (DEFAULT), (DEFAULT), (DEFAULT);Всё просто, вот данные:
INSERT 0 3
# insert into a (b_id) values (1), (2), (3);
INSERT 0 3
# select * from b;Вот что произойдёт если я сделаю дамп без патча:
id
----
1
2
3
(3 rows)
# select * from a;
id | b_id
----+------
1 | 1
2 | 2
3 | 3
(3 rows)
=> pg_dump --data-onlyПечально - данные будут загружены в таблицу a (с FK на b) перед тем, как загрузится b.
...
COPY a (id, b_id) FROM stdin;
1 1
2 2
3 3
\.
...
COPY b (id) FROM stdin;
1
2
3
\.
...
Конечно же данные могут быть загружены иначе, через выключение триггеров вторичных ключей (ALTER TABLE … DISABLE TRIGGER), но это сложновато, и определённо не "круто".
С новым патчем дамп выглядит иначе:
...Порядок теперь правильный. Конечно это не сработает в случае циклической зависимости:
COPY b (id) FROM stdin;
1
2
3
\.
...
COPY a (id, b_id) FROM stdin;
1 1
2 2
3 3
\.
...
# create table a (id serial primary key);Будет выведено предупреждение:
# create table b (id serial primary key, a_id int4 references a(id));
# alter table a add column b_id int4 references b (id);
# insert into a (id) values (DEFAULT);
# insert into b (id, a_id) values (1, 1);
# insert into a (b_id) values (1);
pg_dump: NOTICE: there are circular foreign-key constraints among these table(s):Хорошее дополнение. И респект Tom'у.
pg_dump: a
pg_dump: b
pg_dump: You may not be able to restore the dump without using --disable-triggers or temporarily dropping the constraints.
pg_dump: Consider using a full dump instead of a --data-only dump to avoid this problem.
No comments:
Post a Comment