如何在Postgres中替换表?

8
基本上,我想要做这件事:
begin;
lock table a;
alter table a rename to b;
alter table a1 rename to a;
drop table b;
commit;

即在没有任何人访问它的情况下,获得控制并替换我的旧表格。

你能更具体地说明你卡在哪里或者你似乎无法实现什么吗? - Fabiano Francesconi
没什么关系。当我在命令行尝试时出现了一个错误,但可能是由于已经存在的表或其他原因导致的,我误解了它。因此,你的回答是最好的。;-) - user3416742
3
请指明您遇到的错误信息。 - Fabiano Francesconi
3个回答

19

更简单:

BEGIN;
DROP TABLE a;
ALTER TABLE a1 RENAME TO a;
COMMIT;

DROP TABLE命令无论如何都会在表上获取一个ACCESS EXCLUSIVE锁。显式的LOCK命令也没有更好的效果。而且给死人改名字只是浪费时间。

在准备新表时,您可能希望对旧表进行写入锁定,以防止写入介于两者之间。然后,在该过程的早期发出类似于以下内容的锁定:

LOCK TABLE a IN SHARE MODE;

并发事务试图访问表时会发生什么?这并不简单,请阅读以下内容:

解释为什么你可能会看到像这样的错误消息:

ERROR:  could not open relation with OID 123456

14
请注意,这种方法和原始解决方案都无法保留引用该表的FOREIGN KEY约束、引用该表的视图等。执行DROP操作会失败。如果你使用DROP ... CASCADE命令,则引用该表的视图、约束等也将被删除,并且在你创建/重命名替换表时不会自动重新创建。目前还没有一种方便的方法可以“交换”两个表并保留FK约束等。 - Craig Ringer

0

我会使用答案#13,但我同意,它不会继承约束,并且删除表可能会失败

  • 首先排列相关的约束(例如从pg_dump --schema-only中获取),
  • 删除约束
  • 按照答案#13进行交换
  • 应用约束(从模式转储中获取的SQL片段)

这并没有回答问题。一旦您拥有足够的声望,您将能够评论任何帖子;相反,提供不需要询问者澄清的答案。- 来自审核 - j__carlson

0
创建 SQL 备份,直接在 backup.sql 文件中进行所需更改,然后还原数据库。我在为一组表(Postgres DBMS)添加 INHERIT 以从子表中删除继承字段时使用了这个技巧。

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