För att bara säkerhetskopiera den ena tabellen, använd COPY
inifrån databasen:
COPY user_tbl TO '/path/to/file';
eller pg_dump
från skalet:
pg_dump -t user_tbl mydb > user_tbl.sql
Släpp sedan databasen, återställ din nya version, töm user_tbl
och använd COPY FROM
för att återställa den ena tabellen:
COPY user_tbl FROM '/path/to/file';
eller återställ säkerhetskopian med den ena tabellen från skalet med psql
:
psql -f user_tbl.sql mydb
Identifiera beroende tabeller
Snabbt och smutsigt
Det finns inget som heter "COPY ... CASCADE". Den enklaste metoden att identifiera beroende tabeller skulle vara att starta en transaktion, anropa TRUNCATE tbl CASCADE
och registrera meddelandena du får:
BEGIN;
TRUNCATE user_tbl CASCADE;
NOTICE: truncate cascades to table "tbl1"
NOTICE: truncate cascades to table "tbl2"
NOTICE: truncate cascades to table "tbl3"
Återställ sedan transaktionen - så att ingenting faktiskt ändras:
ROLLBACK;
Var försiktig med det. Om du COMMIT
trunkeringen går igenom.
Långsamt och säkert
Tja, faktiskt inte "långsam", men koden är mycket mer komplex. Detta kräver dock inte ett exklusivt lås på de inblandade borden, så det är mycket renare och säkrare:
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;
Returnerar:
tbl
------
tbl1
tbl2
tbl3
Jag använder en rekursiv CTE
(kräver PostgreSQL 8.4 eller senare) i katalogtabellen pg_constraint
, eftersom varje tabell kan ha beroenden i tur och ordning.
Använd UNION
, inte UNION ALL
för att undvika multipel utvärdering av tabeller som kan vara länkade med flera främmande nycklar direkt eller indirekt.