У меня есть база данных, в которой есть центральный объект, от которого зависит большая часть данных;много справочных таблиц, одно-много объединений и много-много объединений. Мне нужно создать резервную копию всех строк на основе свойства в центральной таблице и иметь возможность восстановить эти строки.
Для целей резервного копирования. Я добавил ON DELETE CASCADE
в соответствующие зависимые таблицы. Поэтому я могу стереть все строки, просто
DELETE FROM main_table WHERE attr=1
Но мне нужно иметь возможность восстановить все строки и ссылки, связанные с ними, в более ранний момент времени. Очки:
pg_dump
не позволяет создавать дампы на основе операторов SQL COPY
не генерирует SQL
Поэтому это решение, которое я предлагаюи я ненавижу этоДля каждой таблицы значение атрибута:
CREATE TABLE tmp_main_table AS SELECT * FROM main_table WHERE attr=val;
CREATE TABLE tmp_table_1 AS SELECT * FROM table_1 WHERE main_table_id IN (SELECT id FROM main_Table WHERE attr=val);
...
Тогда pg_dump -t tmp_main_table -t tmp_table_1 ...
Восстановление затем потребует повторной вставки строк в эти таблицы. У меня есть полный контроль над базой данных, поэтому я могу быть уверен, что идентификаторы ссылочных таблиц остаются прежними, но все это кажется очень хрупким. Есть ли лучший способ?
РЕДАКТИРОВАТЬ: Подробнее
Мы запустили несколько коммерческих сайтов, где клиенты обновляют свои ресурсы через API. Однако часто случается, что вызовы API клиентов ошибочны, и они не замечают этого в течение нескольких дней. В этом случае они позвонят нам и попросят восстановить свой инвентарь до прежнего состояния. Мы должны иметь возможность делать периодические снимки данных клиентом для быстрого восстановления. Вот простой пример БД для иллюстрации: в приведенном ниже примере мне нужно выполнить резервное копирование только строк в product
на customer_id
для последующего восстановления, а при восстановлении я хочу, чтобы остальные строки остались одни и только строкипринадлежащий этому конкретному customer_id
восстановлен:
CREATE TABLE customer (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE color (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE flag (
id SERIAL PRIMARY KEY,
name TEXT
);
CREATE TABLE product (
id SERIAL PRIMARY KEY,
name TEXT,
color_id INTEGER, -- foreign key to color(id)
customer_id INTEGER -- foreign key to customer(id)
);
CREATE TABLE product_flag_join (
id SERIAL PRIMARY KEY,
product_id INTEGER, -- foreign key to product(id)
flag_id -- foreign key to flag(id)
);