Postgresql 博士后断了遗传?

Postgresql 博士后断了遗传?,postgresql,Postgresql,在父表上使用DROP COLUMN\u name后,子表中的某些列不会被删除 如何使用此行为重新分配列,以便将来正确级联删除 如何复制: 有两个表:parent和child。子项从父项继承,并具有相同的列。 在child中添加新列test。在父项中添加新列test。之后,子项中的test将从父项继承。 尝试从父级中删除test——期望从子级中级联删除test。但它仍然存在 CREATE TABLE parent (a INT); CREATE TABLE child () INHERITS (p

在父表上使用
DROP COLUMN\u name
后,子表中的某些列不会被删除

如何使用此行为重新分配列,以便将来正确级联删除

如何复制: 有两个表:
parent
child
。子项从父项继承,并具有相同的列。 在child中添加新列
test
。在父项中添加新列
test
。之后,子项中的
test
将从父项继承。 尝试从父级中删除
test
——期望从子级中级联删除
test
。但它仍然存在

CREATE TABLE parent (a INT);
CREATE TABLE child () INHERITS (parent);
ALTER TABLE child ADD COLUMN test_inherit VARCHAR;
ALTER TABLE parent ADD COLUMN test_inherit VARCHAR;
ALTER TABLE parent DROP COLUMN test_inherit;

这里发生的情况是,表
子表
上的列未标记为继承列:

CREATE TABLE parent (a INT);
CREATE TABLE child (a INT) INHERITS (parent);
NOTICE:  merging column "a" with inherited definition
ALTER TABLE child ADD COLUMN test_inherit VARCHAR;
ALTER TABLE parent ADD COLUMN test_inherit VARCHAR;
NOTICE:  merging definition of column "test_inherit" for child "child"

SELECT attname, attnum, attislocal
FROM pg_attribute
WHERE attrelid = 'child'::regclass AND attnum > 0;

   attname    | attnum | attislocal 
--------------+--------+------------
 a            |      1 | t
 test_inherit |      2 | t
(2 rows)
DROP TABLE parent, child;
CREATE TABLE parent (a INT, test_inherit VARCHAR);
CREATE TABLE child () INHERITS (parent);

SELECT attname, attnum, attislocal
FROM pg_attribute
WHERE attrelid = 'child'::regclass AND attnum > 0;

   attname    | attnum | attislocal 
--------------+--------+------------
 a            |      1 | f
 test_inherit |      2 | f
(2 rows)
attislocal
意味着它是直接在
child
上定义的列,由于从另一个表继承而不是自动创建的

如果定义的子表没有任何列,则这些列将是继承的列:

CREATE TABLE parent (a INT);
CREATE TABLE child (a INT) INHERITS (parent);
NOTICE:  merging column "a" with inherited definition
ALTER TABLE child ADD COLUMN test_inherit VARCHAR;
ALTER TABLE parent ADD COLUMN test_inherit VARCHAR;
NOTICE:  merging definition of column "test_inherit" for child "child"

SELECT attname, attnum, attislocal
FROM pg_attribute
WHERE attrelid = 'child'::regclass AND attnum > 0;

   attname    | attnum | attislocal 
--------------+--------+------------
 a            |      1 | t
 test_inherit |      2 | t
(2 rows)
DROP TABLE parent, child;
CREATE TABLE parent (a INT, test_inherit VARCHAR);
CREATE TABLE child () INHERITS (parent);

SELECT attname, attnum, attislocal
FROM pg_attribute
WHERE attrelid = 'child'::regclass AND attnum > 0;

   attname    | attnum | attislocal 
--------------+--------+------------
 a            |      1 | f
 test_inherit |      2 | f
(2 rows)
如果删除继承父级中的列,则仅删除继承的列:

ALTER TABLE parent DROP COLUMN test_inherit;

\d child
               Table "laurenz.child"
 Column |  Type   | Collation | Nullable | Default 
--------+---------+-----------+----------+---------
 a      | integer |           |          | 
Inherits: parent

在孩子的测试从父母那里继承之后,你能详细说明一下吗。
-有文档说明它被继承了吗?我找不到,只是他们“合并了”。仅根据观察,在子表上显式创建的列似乎不会被认为是继承的,即使父表随后获得了同名的列。问得好。此答案中的代码显示特定列的父列。当您试图更改child中的
test
列时,您将得到关于继承列的错误。所以我得出一个结论,子列从父列继承,可能这是错误的。这是一个非常有趣的问题。链接查询基于仅具有表ID的
pg_inherits
。它从中获取所有列。但肯定还有更多。如果创建一个
父表
和一个继承
父表
子表
,则只将列添加到
父表
,然后从
父表
中删除,这些列将被删除到子表中。但是如果您首先执行以下操作:
ALTER TABLE child NO INHERIT parent
然后
ALTER TABLE child INHERIT parent
,那么请删除并重新添加继承,然后在
parent
中删除列,所有列都不会在
child
中删除。因此,继承似乎不适用于“合并”列。是的,我希望通过
NO-INHERIT
INHERIT
顺序修复遗留数据库中的这些“断开”字段。但是没有运气=\太好了!通过数据库搜索此属性将显示所有“断开”字段。非常感谢。但请编辑第二个示例,并按顺序创建
test\u inherit
字段:首先是子项,然后是父项。问题仍然存在。但是flag
attislocal
解决了我的问题“如何查找和修复这些字段”。再次感谢.PS编辑的相关代码提供了更清晰的说明。我的第二个示例演示了如何以“常规”方式创建表,以便继承列。当然,如果您首先创建
子项
,列将不会被继承。这是关于列的继承属性的一个有趣的事实。如果您试图编辑在父级之前创建的子级中的
test\u inherit
列,您将从Postgre
sql>ALTER TABLE child ALTER column test\u inherit TYPE INT[2019-06-19 16:32:21][42P16]获得错误:无法更改继承列“test\u inherit”
。因此,将此列称为非继承列合法吗?引用文档中关于
attislocal
请注意,列可以在本地同时定义和继承。文档中没有任何信息表明级联删除继承字段不会影响本地创建的属性。这一点很好。我已经编辑了答案并改进了
attislocal
的描述。