В исходной БД есть таблица 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 в скрипт. И это не было бы универсальным решением. Есть ли способ решить это элегантно?