如何更改PostgreSQL数据库表中列的位置?

Huu*_*uze 101 sql database postgresql alter-table

我尝试了以下,但我没有成功:

ALTER TABLE person ALTER COLUMN dob POSITION 37;
Run Code Online (Sandbox Code Playgroud)

Bil*_*win 97

PostgreSQL Wiki中的" 更改列位置 "说:

PostgreSQL目前根据表的attnum列定义列顺序pg_attribute.更改列顺序的唯一方法是重新创建表,或者通过添加列和旋转数据,直到达到所需的布局.

这非常弱,但在他们的辩护中,在标准SQL中,也没有重新定位列的解决方案.支持更改列的序号位置的数据库品牌定义了SQL语法的扩展.

另一个想法发生在我身上:您可以定义一个VIEW指定列的顺序的方式,而不更改基表中列的物理位置.

  • @Kent:令人怀疑的是,postgres开发人员在很大程度上确保了数据的一致性,这肯定适用于pg_dump.毕竟,如果恢复被剔除,那么进行数据库备份的重点是什么? (28认同)
  • @Dana:我认为这就是Wiki文章中“重新创建表”的含义。 (3认同)
  • '转储数据库'::破坏数据的好方法.因此"擦除大量数据库"的效果. (2认同)

Ken*_*Ken 26

这篇文章很老,可能已经解决,但我遇到了同样的问题.我通过创建指定新列顺序的原始表的视图来解决它.

从这里我可以使用视图或从视图中创建一个新表.

    CREATE VIEW original_tab_vw AS
    SELECT a.col1, a.col3, a.col4, a.col2
    FROM original_tab a
    WHERE a.col1 IS NOT NULL --or whatever
    SELECT * INTO new_table FROM original_tab_vw

重命名或删除原始表,并将新表的名称设置为旧表.

  • 好的解决方案,但只复制数据类型(没有主键等) (3认同)
  • 这似乎是一个非常合理的解决方案.太糟糕了,没有任何GUI工具可以自动执行此过程. (2认同)

Vil*_*lle 20

一个,虽然在必须绝对更改列顺序时重新排列列的笨拙选项,并且正在使用外键,但是首先使用数据转储整个数据库,然后仅转储schema(pg_dump -s databasename > databasename_schema.sql).接下来,编辑模式文件以根据需要重新排列列,然后从模式重新创建数据库,最后将数据还原到新创建的数据库中.

  • 为什么投反对票?正如已接受的答案所指出的,引用 PostgreSQL Wiki:“更改列顺序的唯一方法是重新创建表,或者添加列并旋转数据,直到达到所需的布局。” 此解决方案不是最佳的(这些答案都不是在没有内置操作来完成任务的情况下),但它确实提供了一种重新排列表中的列的方法。 (4认同)
  • 实际上,当表是另一个表中的外键时,这是一个很好的解决方案。所有其他解决方案在此方案中均不起作用。最后,使用pg_dump --column-inserts -s databasename> databasename_schema.sql (3认同)
  • 我再说一遍,没有什么好的方法可以做到这一点,如果它们绝对必须重新排列,我上面概述的_是_重新排列列的有效方法。如果您对我的回答投反对票,请评论为什么您认为这是一个不可接受的解决方案。 (2认同)

All*_*win 18

在PostgreSQL中,在添加字段时,它将添加到表的末尾.如果我们需要插入特定位置那么

alter table tablename rename to oldtable;
create table tablename (column defs go here);
insert into tablename (col1, col2, col3) select col1, col2, col3 from oldtable;
Run Code Online (Sandbox Code Playgroud)

  • 您还可以将当前表复制到新的oldtable,如下所示:CREATE TABLE oldtable AS SELECT * FROM tablename; (3认同)
  • 哇,这太好了,我相信这应该是公认的答案! (2认同)
  • 下面是一个真实世界值的示例: insert into newTable (id,created,start,end,message) SELECT id,created,start,end,message FROM oldTable; (2认同)
  • 从一个表移动到另一个表并不容易,因为还有与它们相关的其他对象(例如约束)。 (2认同)
  • 我认为这个解决方案也会弄乱外键。“ALTER TABLE ... RENAME TO ...”似乎相应地更改了其他表中现有的外键关系。这意味着最终外键指向“oldtable”,但数据位于新表中。我假设在正确删除“oldtable”之前需要手动迁移所有外键关系。 (2认同)

Mik*_*use 9

我认为你目前不能:在Postgresql维基上看到这篇文章.

本文的三个解决方法是:

  1. 重新创建表格
  2. 添加列并移动数据
  3. 隐藏视图中的差异.


小智 5

在PGAdmin中打开表,并在底部的SQL窗格中复制SQL Create Table语句.然后打开查询工具并粘贴.如果表有数据,请将表名更改为"new_name",否则,删除"删除表"行中的注释" - ".根据需要编辑列序列.记住最后一栏中丢失/多余的逗号,以防你移动它.执行新的SQL Create Table命令.刷新......瞧.

对于设计阶段的空表,这种方法非常实用.

如果表有数据,我们也需要重新排列数据的列序列.这很简单:用于INSERT将旧表导入其新版本:

INSERT INTO new ( c2, c3, c1 ) SELECT * from old;
Run Code Online (Sandbox Code Playgroud)

...其中c2,c3,c1是列c1,c2,c3旧表在其新职位.请注意,在这种情况下,您必须为已编辑的"旧"表使用"新"名称,否则您将丢失数据.如果列名称很多,则长和/或复杂使用与上面相同的方法将新表结构复制到文本编辑器中,并在将其复制到INSERT语句之前创建新列列表.

在检查DROP完所有之后,旧表并将"新"名称更改为"旧"使用ALTER TABLE new RENAME TO old;,您就完成了.

  • 很确定这个过程也需要重新创建所有 FK 约束。 (2认同)