2010-12-01 9 views
9

Ich habe eine Tabelle, foo. Im Sinne einer schnellen Aktualisierung/Bereitstellung von meiner Seite habe ich eine neue Tabelle, tmp_foo, einige neue Daten enthalten, indem Sie:Löschen einer Tabelle in PostgreSQL ohne eine zugehörige Sequenz zu löschen

create table tmp_foo (like foo including constraints including defaults including indexes); 

Nun hat jeder Tisch eine PK id Spalte hat, die wie folgt aussieht:

Der wichtige Punkt ist, dass beide Tabellen auf die exakt gleiche Sequenz foo_id_seq beruhen. Es gibt keine tmp_foo_id_seq. Das scheint für meine Zwecke in Ordnung zu sein.

Danach lud ich tmp_foo mit neuen Daten und umbenannt die Tabellen, so dass tmp_foo als die eigentlichen foo übernahmen, und die ursprünglichen foo wurde foo_old. Jetzt versuche ich foo_old zu fallen:

db=> drop table foo_old ; 
ERROR: cannot drop table foo_old because other objects depend on it 
DETAIL: default for table foo_old column id depends on sequence foo_id_seq 

Fair enough, die id Spalte Standard hängt noch von der Sequenz.

db=> alter table foo_old alter column id drop default; 

Hier ist der Kicker.

db=> drop table foo_old ; 
ERROR: cannot drop table foo_old because other objects depend on it 
DETAIL: default for table foo column id depends on sequence foo_id_seq 

So foo_old nicht mehr sichtbare Abhängigkeit von der Sequenz hat, aber es immer noch versucht, die Sequenz zusammen mit dem Tisch fallen zu lassen (und offensichtlich nicht, da die neue Tabelle hängt davon ab).

Die Frage ist also zweiteilige:

  1. Warum wird die Sequenz noch mit der alten Tabelle verknüpft?
  2. Gibt es einen Weg, um dies, die nicht mit sich bringt die neue Tabelle auf eine neue oder andere Sequenz depend machen (wenn die würde sogar Hilfe)?

(auf PostgreSQL 8.4)

Antwort

19

Try this:

 
ALTER SEQUENCE foo_id_seq OWNED BY NONE 

dann sollten Sie in der Lage sein, den Tisch fallen zu lassen.

Um die "Besitzer" einer Sequenz verwenden Sie die folgende Abfrage

 
SELECT s.relname as sequence_name, 
     n.nspname as sequence_schema, 
     t.relname as related_table, 
     a.attname as related_column 
    FROM pg_class s, pg_depend d, pg_class t, pg_attribute a, pg_namespace n 
    WHERE s.relkind  = 'S' 
    AND n.oid   = s.relnamespace 
    AND d.objid  = s.oid 
    AND d.refobjid = t.oid 
    AND (d.refobjid, d.refobjsubid) = (a.attrelid, a.attnum) 
+1

Aha abrufen. Das hat funktioniert. (Eigentlich, seit ich paranoid war, habe ich den neuen Tisch zum Besitzer gemacht, anstatt keinen.) Wissen Sie zufällig, wie man den Besitzer einer Sequenz kontrolliert? '\ d' zeigt es nicht an und' select * from foo_id_seq' auch nicht. –

+0

Ich weiß nicht, wie man eine SQL-Anweisung in Kommentaren richtig formatiert, also fügte ich die Aussage meiner Antwort hinzu –