Существует ли способ восстановления данных в базе данных Postgres из дампа в том порядке, в котором они были вставлены в исходную базу данных, чтобы избежать нарушения проверочного ограничения? - PullRequest
0 голосов
/ 27 марта 2020

В исходной БД есть таблица accounts, которую мне нужно клонировать. Я создал дамп с

pg_dump --verbose --host=my_host --port=5432 --username=postgres --format=c -n "core" -n "public" my_database -f dumpfile

при восстановлении из дампа с помощью

pg_restore --host=another_host --port=5432 --username=postgres --format=c -d my_database dumpfile

Я получаю ошибку:

COPY failed for table "accounts": ERROR:  new row for relation "accounts" violates check constraint "valid_parent_account"
DETAIL:  Failing row contains (685d6529-cd0a-41be-be5a-c9aea60aa8c5, 139788c6-197f-40f1-a7f7-274a23af9062, null, t, 2020-02-06 15:05:18.571918, 2020-03-24 16:14:47.061383, null, null, null, null, null).

это потому что core.accounts ' s DDL:

CREATE TABLE core.accounts (
    id uuid NOT NULL,
    parent_id uuid NULL,
...
    CONSTRAINT valid_parent_account null
);

и функция core.valid_parent_account:

CREATE OR REPLACE FUNCTION core.is_valid_parent_account(parent_account_id uuid)
 RETURNS boolean
 LANGUAGE plpgsql
AS $function$
declare good boolean;
BEGIN   
    good := false;
    if (parent_account_id is null) or (exists(select 1 from core.accounts where id = parent_account_id and parent_id is null)) then
         good := true;
    end if;

    return good;
END;
$function$
;

, что означает, что строка должна иметь либо parent_id = NULL, либо существующую id из та же таблица. Результат условия зависит от порядка вставки. Если он не совпадает с исходной таблицей, он нарушает ограничение и приводит к ошибке, описанной выше.

Я попытался восстановить схему и данные отдельно pg_restore -s и pg_restore ---disable-triggers --data-only --superuser=postgres после него. Это не помогло: ограничение не является триггером.

Полагаю, это можно сделать, удалив (или изменив) функцию, а затем добавив ее обратно. Но я бы хотел поставить dump / restore в скрипт. И это не было бы универсальным решением. Есть ли способ решить это элегантно?

...