在PostgreSQL中删除一个表而不删除关联的序列

19

我有一个名为foo的表。为了快速升级/部署我的网站,我创建了一个新表tmp_foo来包含一些新数据,方法如下:

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

现在每个表都有一个主键id列,看起来像这样:

   Column    |         Type          |                                Modifiers                                 
-------------+-----------------------+--------------------------------------------------------------------------
 id          | integer               | not null default nextval('foo_id_seq'::regclass)

重要的一点是两个表都依赖于完全相同的序列 foo_id_seq,并且不存在 tmp_foo_id_seq。这对我的目的来说似乎没问题。

之后,我使用新数据加载了 tmp_foo 并将表重命名,使得 tmp_foo 取代了真正的 foo,原始的 foo 成为了 foo_old。现在我试图删除 foo_old

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

可以理解,id列的默认值仍取决于序列。

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

这就是问题的关键。

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

因此,foo_old在序列方面已经没有任何可见的依赖性,但它仍然试图删除序列以及表(显然不会成功,因为新表依赖于该序列)。

所以问题有两个部分:

  1. 为什么序列仍然与旧表相关联?
  2. 是否有任何方法可以解决这个问题,而不需要使新表依赖于新的或不同的序列(如果这样做甚至有帮助的话)?

(在 PostgreSQL 8.4 上)

1个回答

34

请尝试执行以下命令:

ALTER SEQUENCE foo_id_seq OWNED BY NONE

然后您就可以删除该表了。

要检索序列的“owner”,请使用以下查询:

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)

2
啊哈。成功了。(实际上,由于我很多疑,我把新表作为所有者,而不是没有。)你知道如何检查序列的所有者吗?\d 不显示它,select * from foo_id_seq 也不显示。 - Alison R.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接