За да архивирате само една таблица, използвайте COPY
от вътрешността на базата данни:
COPY user_tbl TO '/path/to/file';
или pg_dump
от обвивката:
pg_dump -t user_tbl mydb > user_tbl.sql
След това изтрийте базата данни, възстановете новата си версия, изпразнете user_tbl
и използвайте COPY FROM
за възстановяване на една таблица:
COPY user_tbl FROM '/path/to/file';
или възстановете резервното копие с една таблица от обвивката с psql
:
psql -f user_tbl.sql mydb
Идентифицирайте зависими таблици
Бързо и мръсно
Няма такова нещо като "КОПИРАНЕ ... КАСКАДА". Най-простият метод за идентифициране на зависими таблици би бил да стартирате транзакция, извикайте TRUNCATE tbl CASCADE
и запишете известията, които получавате:
BEGIN;
TRUNCATE user_tbl CASCADE;
NOTICE: truncate cascades to table "tbl1"
NOTICE: truncate cascades to table "tbl2"
NOTICE: truncate cascades to table "tbl3"
След това върнете обратно транзакцията - така че нищо не се променя:
ROLLBACK;
Внимавай с това. Ако COMMIT
съкращаването минава.
Бавно и сигурно
Е, всъщност не е "бавен", но кодът е много по-сложен. Това обаче не изисква изключително заключване на участващите маси, така че е много по-чисто и по-безопасно:
WITH RECURSIVE x AS (
SELECT conrelid::regclass
FROM pg_constraint
WHERE confrelid = 'user_tbl'::regclass
UNION
SELECT p.conrelid::regclass
FROM x
JOIN pg_constraint p ON p.confrelid = x.conrelid
)
SELECT conrelid::text AS tbl
FROM x;
Връща:
tbl
------
tbl1
tbl2
tbl3
Използвам рекурсивен CTE
(изисква PostgreSQL 8.4 или по-нова версия) в каталожната таблица pg_constraint
, защото всяка таблица може да има зависимости на свой ред.
Използвайте UNION
, а не UNION ALL
за избягване на множество оценки на таблици, които могат да бъдат свързани с множество външни ключове пряко или косвено.