我有一个包含1600列的表,并希望在其中添加更多字段,但根据数据库规则,由于达到了更高的限制,因此不允许创建更多字段。
所以我决定从表中删除一些不需要的字段,然后我就这样做了。我再次试图在该表中添加几个字段,但它引发的相同错误是1600列,你不能添加更多。
我浏览了postgresql的其他表" pg_attribute "并且所有这些字段都在那里,并且删除参数= True。
到目前为止我尝试了什么
Drop Constraints将表数据带入另一个表Truncate Table 重新创建约束将数据重新复制到主表。
但是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限制。现在它不允许我放弃那里的字段 表。
我已经在magento-odoo连接器中解决了这个问题,它只会 同步所需的属性,但我应该为已同步的属性做什么 字段如何删除它????
即使丢桌也不是一个正确的方法,因为它很大而且非常 重要的表格,所以我可以冒任何风险。
我想做什么
我想简单地从表中删除这些列并且需要 而是添加其他几列。
这个问题还有其他可能的解决方案吗?
任何帮助都会非常感激。
答案 0 :(得分:2)
永远不要直接混淆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;
答案 1 :(得分:1)
DROP COLUMN表单没有物理删除列,只是使它对SQL操作不可见。表中的后续插入和更新操作将为列存储空值。因此,删除列很快,但不会立即减少表的磁盘大小,因为已删除列所占用的空间不会被回收。随着现有行的更新,该空间将随着时间的推移而被回收
要强制立即回收已删除列占用的空间,可以执行ALTER TABLE的一种形式,以执行整个表的重写。这导致重建每一行,并将删除的列替换为空值。