如何从父表中删除列并将其传播到所有子表

时间:2013-01-09 12:20:38

标签: postgresql

有人可以帮我吗?我有一组从单个父表继承的表(现在所有这些表都包含数据)。

我需要从父表中删除特定列,并且应自动删除所有继承表中的相同列。这可能吗?

当我尝试这个时,只删除了父表列。我也在alter table中尝试了cascade选项,但没有结果。

我正在使用postgreSql 8.3

3 个答案:

答案 0 :(得分:3)

我刚刚遇到Postgres 9.3的同样问题。 该问题似乎只存在于以下场景中:

1)

create table parent_table(a int);
create table child_table(a int) inherits (parent_table);

2)

create table parent_table(a int);
create table child_table(a int);
alter table child_table INHERIT parent_table;

场景2)比1)更可能,因为1)你可以改为:

create table parent_table(a int);
create table child_table() inherits (parent_table);

并在两个表中获得相同的列。

在方案2)中,child_table必须包含所有parent_table的列及其约束。根据Postgres documentation

  

INHERIT parent_table

     

此表单将目标表添加为指定父表的新子表。随后,针对父级的查询将包括目标表的记录。要作为子项添加,目标表必须已包含与父项相同的所有列(它也可能包含其他列)。列必须具有匹配的数据类型,如果它们在父级中具有NOT NULL约束,则它们在子级中也必须具有NOT NULL约束。

     

对于父级的所有CHECK约束,还必须存在匹配的子表约束。目前不考虑UNIQUE,PRIMARY KEY和FOREIGN KEY约束,但这可能在将来发生变化。

这样做的结果是,如果您在事后添加了对表的继承,然后删除父表中的列,那么即使您使用DROP CASCADE,也不会从子表中删除该列。 / p>

答案 1 :(得分:1)

当我们通过遍历所有继承的表来添加列时,从主表中删除列并不会从每个继承的表中删除,它会从每个继承的表中删除,只有当我们通过将列添加到主表来添加列时。也没有 'CASCADE;是必须的。 (用 PostgreSQl 检查)

ALTER TABLE 'Table_Name' ADD COLUMN IF NOT EXISTS 'Col_Name' 'type'
ALTER TABLE 'Table_Name' DROP COLUMN IF EXISTS 'Col_Name'

答案 2 :(得分:0)

当在父表中删除列时,它也应该在继承的表中被删除。 manual说:

  

ALTER TABLE将传播列数据定义中的任何更改   检查继承层次结构中的约束。再次,下降   父表上的列或约束只能在使用时使用   CASCADE选项。 ALTER TABLE遵循相同的重复规则   在CREATE TABLE期间应用的列合并和拒绝。

试试这个:

create table parent_table(a int, b int);
create table child_table(c int) inherits (parent_table);

结果:

# \d child_table 
  Table "public.child_table"
 Column |  Type   | Modifiers 
--------+---------+-----------
 a      | integer | 
 b      | integer | 
 c      | integer | 
Inherits: parent_table

现在让我们在parent_table中删除一列:

alter table parent_table drop column a cascade;

结果:

\d child_table 
  Table "public.child_table"
 Column |  Type   | Modifiers 
--------+---------+-----------
 b      | integer | 
 c      | integer | 
Inherits: parent_table

DROP COLUMN已按预期传播到子表。

如果您的表定义得到不同的结果,您应该在问题和drop SQL语句中包含这些定义。