【发布时间】:2010-09-22 02:14:06
【问题描述】:
我尝试了以下方法,但没有成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
【问题讨论】:
标签: sql database postgresql alter-table
我尝试了以下方法,但没有成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
【问题讨论】:
标签: sql database postgresql alter-table
“Alter column position”在 PostgreSQL Wiki 中说:
PostgreSQL 当前定义了列 基于
attnum列的顺序pg_attribute表。唯一的办法 更改列顺序是通过 重新创建表,或通过添加 列和旋转数据,直到你 达到所需的布局。
这很弱,但在他们的防御中,在标准 SQL 中,也没有重新定位列的解决方案。支持更改列序号位置的数据库品牌正在定义 SQL 语法的扩展。
我想到了另一个想法:您可以定义一个 VIEW 来指定您喜欢的列顺序,而无需更改列在基表中的物理位置。
【讨论】:
在 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;
【讨论】:
ALTER TABLE ... RENAME TO ... 似乎相应地改变了其他表中现有的外键关系。这意味着最终外键指向oldtable,但数据在新表中。我假设需要手动迁移所有外键关系,然后才能正确删除 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获取建表SQL
pg_dump 查询以使用数据创建重新排序的表可以通过运行以下简单命令来使用它:
./reorder.py -n schema -d database table \
first_col second_col ... penultimate_col ultimate_col --migrate
它会打印出 sql,以便您验证和测试它,这是我基于 pg_dump 的一个重要原因。你可以找到github repo here。
【讨论】:
我使用 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 步: 现在我们可以删除视图,删除源表并以旧名称重命名新表。 戏法成功结束。
【讨论】:
有一些解决方法可以做到这一点:
重新创建整个表
在当前表中创建新列
创建视图
【讨论】: