删除列不会完全删除列引用 - postgresql



我有一个包含 1600 列的表,并希望在其中添加更多字段,但根据数据库规则,由于达到上限,不允许创建更多字段。

所以我决定从表中删除一些不需要的字段,我做到了。我再次尝试在该表中添加一些字段,但它引发了相同的错误,即 1600 列无法添加更多。

我浏览了 postgresql">pg_attribute"的其他表,所有这些字段都在那里并且具有删除参数 = True。

到目前为止我尝试过什么

删除约束 将表数据放入另一个表 截断表 重新创建约束 将数据重新复制到主表。

但是删除的列仍然存在于pg_attributes表中。

我也试图从pg_attribute中删除该记录,但后来它 给我这样的错误。

ERROR:  catalog is missing 1 attribute(s) for relid 208996
********** Error **********
ERROR: catalog is missing 1 attribute(s) for relid 208996
SQL state: XX000

为什么我们有这么多列的原因是

我们有odoo-magento(odoo使用的postgresql db)集成和 在Magento有超过60000种产品,并拥有3000种独特的产品 属性,因此在连接器中,所有这些属性都创建为字段 在产品表中,我已经同步了 magento -> odoo 产品和 已达到 1600 限制。现在我不允许从中删除字段 桌子。

我已经在洋红色连接器中修复了这个问题,它只会 同步所需的属性,但我应该为已经同步的属性做什么 字段如何删除它????

即使放下桌子也不是一种正确的方法,因为它很大而且非常 重要的表格,所以我可以承担任何风险。

我想做什么

我想简单地从表中删除这些列,并且需要 改为添加其他几列。

这个问题还有其他可能的解决方案吗?

任何帮助将不胜感激。

永远不要直接惹pg_attribute。如果您这样做了,可能是时候从备份还原了。

当一个列被删除时,PostgreSQL实际上并没有删除它,而是更改名称并将其标记为已删除。

CREATE TABLE testtab (
id integer PRIMARY KEY,
dropme text NOT NULL,
val text NOT NULL
);
ALTER TABLE testtab DROP dropme;
SELECT attname, attnum, attisdropped
FROM pg_attribute
WHERE attrelid = 'testtab'::regclass
AND attnum > 0
ORDER BY attnum;
┌──────────────────────────────┬────────┬──────────────┐
│           attname            │ attnum │ attisdropped │
├──────────────────────────────┼────────┼──────────────┤
│ id                           │      1 │ f            │
│ ........pg.dropped.2........ │      2 │ t            │
│ val                          │      3 │ f            │
└──────────────────────────────┴────────┴──────────────┘
(3 rows)

所以我想删除的列仍然计入列限制。

我能想到一种不太舒服的方法来摆脱它:

BEGIN;
CREATE TABLE testtab_2 (LIKE testtab INCLUDING ALL);
INSERT INTO testtab_2 SELECT * FROM testtab;
DROP TABLE testtab;
ALTER TABLE testtab_2 RENAME TO testtab;
COMMIT;

如手册中所述

DROP COLUMN 窗体不会以物理方式删除该列,而只是使其对 SQL 操作不可见。表中的后续插入和更新操作将存储列的 null 值。因此,删除列很快,但它不会立即减小表的磁盘大小,因为不会回收已删除列占用的空间。随着现有行的更新,空间将随着时间的推移而回收。

要强制立即回收已删除列占用的空间,可以执行 ALTER TABLE 的一种形式,该形式执行整个表的重写。这会导致重建每一行,并将删除的列替换为 null 值。

最新更新