Postgres: hur hitta dolda relationer (pg_depend)

Tråden skapades och har fått 7 svar. Det senaste inlägget skrevs .
1

Ciao!

Hoppas någon är vaken så här tidigt *hrrmmm*....

Känner någon till hur man kan joina postgres interna tabell pg_depend för att få fram namnen på tabeller som relaterar till varandra?

  • Medlem
  • Kiruna
  • 2006-06-22 11:45

Har faktiskt inte gjort detta direkt mot system-katalogen, men väl mot information_schema, då såg det ut så här:

SELECT tc.table_name, rc.unique_constraint_name, rc.constraint_name, tc2.table_name AS related_table_name, rc.match_option, rc.update_rule, rc.delete_rule
FROM information_schema.table_constraints tc
JOIN information_schema.referential_constraints rc ON (tc.constraint_catalog, tc.constraint_schema, tc.constraint_name)=(rc.unique_constraint_catalog, rc.unique_constraint_schema, rc.unique_constraint_name)
JOIN information_schema.table_constraints tc2  ON (rc.constraint_catalog, rc.constraint_schema, rc.constraint_name)=(tc2.constraint_catalog, tc2.constraint_schema, tc2.constraint_name)
WHERE tc2.constraint_type='FOREIGN KEY';

Som vanligt med information_schema tar den hänsyn till vilka objekt den aktuelle användaren har tillgång till, vilket ju kan vara både en för- och nackdel.

Den sql:en gav inget resultat, dessvärre...

Jag misstänker att jag har en "orphaned" relation i den tabellen, då jag har en kolumn i en tabell som jag inte får radera eftersom "other objects depend on it". Det gör dock inga andra objek; syns inget under info-sidan för tabellen i pgadmin, och jag har varit genom samtliga tabeller och views och inget, precis som det ska vara, relaterar till kolumnen i fråga...

  • Medlem
  • Kiruna
  • 2006-06-23 12:58

SQL-frågan hämtade ju tabell-relationer och inte kolumnberoenden, så det var kanske inte så konstigt att du inte fick något resultat...

Följande hämtar alla constraints som en viss kolumn är beroende av:

SELECT c.relname, a.attname, con.conname, d.deptype
FROM pg_attribute a
JOIN pg_class c ON a.attrelid=c.oid
JOIN pg_depend d ON c.oid=d.refobjid AND a.attnum=d.refobjsubid
JOIN pg_constraint con ON d.objid=con.oid
WHERE c.relname='tabellnamn' AND a.attname='kolumnnamn';

Det finns visserligen fler saker som en kolumn kan vara beroende av, men ta bara bort den sista joinen så ser du ju om det finns något i pg_depends överhuvudtaget:

SELECT c.relname, a.attname, d.*
FROM pg_attribute a
JOIN pg_class c ON a.attrelid=c.oid
JOIN pg_depend d ON c.oid=d.refobjid AND a.attnum=d.refobjsubid
WHERE c.relname='tabellnamn' AND a.attname='kolumnnamn';

Förresten, vad händer om du försöker göra DROP ... CASCADE? (I en transaktion givetvis, så du kan se vad som händer och ångra dig om det skulle behövas...)

Ursprungligen av spot:

Det finns visserligen fler saker som en kolumn kan vara beroende av, men ta bara bort den sista joinen så ser du ju om det finns något i pg_depends överhuvudtaget:

SELECT c.relname, a.attname, d.*
FROM pg_attribute a
JOIN pg_class c ON a.attrelid=c.oid
JOIN pg_depend d ON c.oid=d.refobjid AND a.attnum=d.refobjsubid
WHERE c.relname='tabellnamn' AND a.attname='kolumnnamn';

Kolumnen som pg klagar över är relaterad, men som jag menar inte är det, finns inte med i detta resultat...

Citat:

Förresten, vad händer om du försöker göra DROP ... CASCADE? (I en transaktion givetvis, så du kan se vad som händer och ångra dig om det skulle behövas...)

Det vågar jag inte, eftersom jag då riskerar att nollaställa en ev relaterad, men förbisedd, kolumn någon annanstans... Anledningen till att jag vill ta bort den är att jag skapade en kopia av den men med en annan typ (varchar isf int), som jag sedan flyttade över alla relationer och primary key till.

  • Medlem
  • Kiruna
  • 2006-06-26 12:52
Ursprungligen av scooterbabe:

Kolumnen som pg klagar över är relaterad, men som jag menar inte är det, finns inte med i detta resultat...

Dum fråga kanske, men du ändrade väl WHERE-satsen så att den innehöll din kolumns (och tabells) namn?

Ursprungligen av scooterbabe:

Det vågar jag inte, eftersom jag då riskerar att nollaställa en ev relaterad, men förbisedd, kolumn någon annanstans...

Just därför ska det göras i en transaktion. Om du gör:

BEGIN;
DROP ... CASCADE;

Så ser du ju vilka övriga objekt som också droppas. Är det då något som är galet gör du bara ROLLBACK. Är det OK gör du COMMIT.

PS. Allt sådant här är i mitt tycke mycket enklare i psql än i vare sig web-baserade eller andra grafiska gränssnitt.

  • Medlem
  • Stockholm
  • 2006-06-25 19:16
Ursprungligen av scooterbabe:

Den sql:en gav inget resultat, dessvärre...

Jag misstänker att jag har en "orphaned" relation i den tabellen, då jag har en kolumn i en tabell som jag inte får radera eftersom "other objects depend on it". Det gör dock inga andra objek; syns inget under info-sidan för tabellen i pgadmin, och jag har varit genom samtliga tabeller och views och inget, precis som det ska vara, relaterar till kolumnen i fråga...

Jag har upptäckt att phpPgAdmin (om du använder det) ibland inte vill visa selects från systemtabeller - saker som ger "tomma" resultat i phppgadmin ger bra output i konsol-klienten (psql).

/Kalle

Senast redigerat 2006-06-25 21:07
  • Medlem
  • Mölndal
  • 2006-06-26 12:41

Kanske inte går av nån anledning, men varför inte ta kopia på databasen och prova?

1
Bevaka tråden