我尝试了以下方法,但没有成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
我尝试了以下方法,但没有成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
PostgreSQL Wiki 中的“更改列位置”说:
PostgreSQL 目前根据表的
attnum
列定义列顺序pg_attribute
。更改列顺序的唯一方法是重新创建表,或者添加列并旋转数据,直到达到所需的布局。
这很弱,但在他们的辩护中,在标准 SQL 中,也没有重新定位列的解决方案。支持更改列序号位置的数据库品牌正在定义 SQL 语法的扩展。
我想到了另一个想法:您可以定义 aVIEW
来指定您喜欢的列顺序,而无需更改列在基表中的物理位置。
在 PostgreSQL 中,当添加一个字段时,它会被添加到表的末尾。如果我们需要插入特定位置,那么
alter table tablename rename to oldtable;
create table tablename (column defs go here); ### with all the constraints
insert into tablename (col1, col2, col3) select col1, col2, col3 from oldtable;
这篇文章很旧并且可能已解决,但我遇到了同样的问题。我通过创建指定新列顺序的原始表的视图来解决它。
从这里我可以使用视图或从视图创建一个新表。
创建视图 original_tab_vw AS 选择 a.col1、a.col3、a.col4、a.col2 FROM original_tab 一个 WHERE a.col1 IS NOT NULL -- 或其他
从 original_tab_vw 中选择 * INTO new_table
重命名或删除原始表并将新表的名称设置为旧表。
一个,尽管当必须绝对更改列顺序并且使用外键时重新排列列的笨拙选项是首先转储整个数据库的数据,然后只转储模式(pg_dump -s databasename > databasename_schema.sql
)。接下来编辑模式文件以根据需要重新排列列,然后从模式重新创建数据库,最后将数据恢复到新创建的数据库中。
在 PGAdmin 中打开表并在底部的 SQL 窗格中复制 SQL Create Table 语句。然后打开查询工具并粘贴。如果表有数据,将表名改为'new_name',如果没有,删除Drop Table行中的注释“--”。根据需要编辑列顺序。请注意最后一列中缺少/多余的逗号,以防您移动了它。执行新的 SQL 创建表命令。刷新和...瞧。
对于设计阶段的空表,这种方法非常实用。
如果表有数据,我们也需要重新排列数据的列顺序。这很简单:使用INSERT
以下命令将旧表导入新版本:
INSERT INTO new ( c2, c3, c1 ) SELECT * from old;
... 其中c2
, c3
,c1
是旧表的列c1
, c2
,c3
处于新位置。请注意,在这种情况下,您必须为已编辑的“旧”表使用“新”名称,否则您将丢失数据。如果列名很多、长和/或复杂,请使用与上述相同的方法将新表结构复制到文本编辑器中,并在将新列列表复制到INSERT
语句之前在那里创建新列列表。
检查一切正常后,DROP
使用旧表并将“新”名称更改为“旧” 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,以便您可以验证和测试它,这是我基于它的一个重要原因pg_dump
。你可以在这里找到 github repo。
我使用 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
第 3 步:
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 * into pg 之后会创建 bigint 类型的 insetad bigserial。
第 4 步:现在我们可以删除视图、删除源表并以旧名称重命名新表。戏法顺利结束。
有一些解决方法可以使其成为可能:
重新创建整个表
在当前表中创建新列
创建视图