Aby wykonać kopię zapasową tylko jednej tabeli, użyj COPY
z wnętrza bazy danych:
COPY user_tbl TO '/path/to/file';
lub pg_dump
z powłoki:
pg_dump -t user_tbl mydb > user_tbl.sql
Następnie upuść bazę danych, przywróć nową wersję, opróżnij user_tbl
i użyj COPY FROM
aby przywrócić jedną tabelę:
COPY user_tbl FROM '/path/to/file';
lub przywróć kopię zapasową z jedną tabelą z powłoki za pomocą psql
:
psql -f user_tbl.sql mydb
Zidentyfikuj tabele zależne
Szybko i brudno
Nie ma czegoś takiego jak „KOPIUJ… KASKADA”. Najprostszą metodą identyfikacji tabel zależnych byłoby rozpoczęcie transakcji, wywołanie TRUNCATE tbl CASCADE
i zapisz otrzymane powiadomienia:
BEGIN;
TRUNCATE user_tbl CASCADE;
NOTICE: truncate cascades to table "tbl1"
NOTICE: truncate cascades to table "tbl2"
NOTICE: truncate cascades to table "tbl3"
Następnie wycofaj transakcję - tak naprawdę nic się nie zmienia:
ROLLBACK;
Ostrożnie z tym. Jeśli COMMIT
skrócony przechodzi.
Powoli i pewnie
Cóż, właściwie nie „wolno”, ale kod jest o wiele bardziej złożony. Nie wymaga to jednak wyłącznej blokady na zaangażowanych stołach, więc jest o wiele czystsze i bezpieczniejsze:
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;
Zwroty:
tbl
------
tbl1
tbl2
tbl3
Używam rekurencyjnego CTE
(wymaga PostgreSQL w wersji 8.4 lub nowszej) w tabeli katalogu pg_constraint
, ponieważ każda tabela może mieć kolejno zależności.
Użyj UNION
, a nie UNION ALL
aby uniknąć wielokrotnej oceny tabel, które mogą być połączone z wieloma kluczami obcymi bezpośrednio lub pośrednio.