我尝试了以下操作,但未成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
我尝试了以下操作,但未成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
Answers:
PostgreSQL Wiki中的“ 更改列位置 ”说:
PostgreSQL当前基于表的
attnum
列定义列顺序pg_attribute
。更改列顺序的唯一方法是重新创建表,或者添加列并旋转数据,直到达到所需的布局为止。
这是相当薄弱的,但是在标准SQL中,在他们的辩护中,也没有解决方法来重新定位列。支持更改列的顺序位置的数据库品牌正在定义SQL语法的扩展。
我想到了另一个想法:您可以定义a VIEW
,以指定您喜欢的列顺序,而无需更改列在基表中的物理位置。
在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;
这篇文章很旧,可能已经解决了,但我遇到了同样的问题。我通过创建指定新列顺序的原始表的视图来解决它。
从这里,我可以使用视图或从视图创建新表。
创建视图original_tab_vw AS 选择a.col1,a.col3,a.col4,a.col2 从original_tab a.col1不为空的地方-或其他任何地方
SELECT * INTO new_table FROM original_tab_vw
重命名或删除原始表,然后将新表的名称设置为旧表。
尽管在必须绝对更改列顺序且使用外键时重新排列列的方法很笨拙,但它还是要先转储整个数据库的数据,然后再转储模式(pg_dump -s databasename > databasename_schema.sql
)。接下来,编辑架构文件以根据需要重新排列列,然后从架构中重新创建数据库,最后将数据还原到新创建的数据库中。
在PGAdmin中打开表,然后在底部的SQL窗格中复制SQL Create Table语句。然后打开查询工具并粘贴。如果表中有数据,请将表名更改为“ new_name”,否则,在“删除表”行中删除注释“-”。根据需要编辑列顺序。请注意最后一列中丢失/多余的逗号(如果已移动)。执行新的“ SQL创建表”命令。刷新并...瞧瞧。
对于设计阶段的空表,此方法非常实用。
如果表中有数据,我们还需要重新排列数据的列顺序。这很容易:使用以下INSERT
命令将旧表导入到新表中:
INSERT INTO new ( c2, c3, c1 ) SELECT * from old;
...其中c2
,c3
,c1
是列c1
,c2
,c3
旧表在其新职位。请注意,在这种情况下,必须为已编辑的“旧”表使用“新”名称,否则将丢失数据。如果列名很多,很长和/或很复杂,则使用与上述相同的方法将新表结构复制到文本编辑器中,并在将新表列表复制到INSERT
语句之前在其中创建新列列表。
在检查DROP
完一切之后,使用旧表并将“ new”名称更改为“ old” ALTER TABLE new RENAME TO old;
,即可完成操作。
我当时正在对许多表进行重新排序,并且不想一遍又一遍地编写相同的查询,因此我编写了一个脚本来为我完成所有这些工作。本质上,它:
pg_dump
pg_dump
查询以创建具有数据的重新排序的表可以通过运行以下简单命令来使用它:
./reorder.py -n schema -d database table \
first_col second_col ... penultimate_col ultimate_col --migrate
它会打印出sql,以便您可以验证和测试它,这是我基于sql的一个重要原因pg_dump
。您可以在这里找到github仓库。
我使用Django,如果您不想头痛,它需要每个表中的id列。不幸的是,我很粗心,我的表bp.geo_location_vague没有包含该字段。我开始了一点小技巧。第1步:
CREATE VIEW bp.geo_location_vague_vw AS
SELECT
a.id, -- I change order of id column here.
a.in_date,
etc
FROM bp.geo_location_vague a
第2步:(不创建表-表将自动创建!)
SELECT * into bp.geo_location_vague_cp2 FROM bp.geo_location_vague_vw
第三步:
CREATE SEQUENCE bp.tbl_tbl_id_seq;
ALTER TABLE bp.geo_location_vague_cp2 ALTER COLUMN id SET DEFAULT nextval('tbl_tbl_id_seq');
ALTER SEQUENCE bp.tbl_tbl_id_seq OWNED BY bp.geo_location_vague_cp2.id;
SELECT setval('tbl_tbl_id_seq', COALESCE(max(id), 0)) FROM bp.geo_location_vague_cp2;
因为我需要在表中使用bigserial伪类型。将SELECT *插入pg后,将创建bigint类型的insetad bigserial。
步骤4:现在我们可以删除视图,删除源表并以旧名称重命名新表。俩成功结束了。
有一些变通办法使之成为可能:
重新创建整个表
在当前表中创建新列
创建一个视图