[英]How do I alter the position of a column in a PostgreSQL database table?
我嘗試了以下方法,但沒有成功:
ALTER TABLE person ALTER COLUMN dob POSITION 37;
PostgreSQL Wiki 中的“更改列位置”說:
PostgreSQL 當前基於
pg_attribute
表的attnum
列定義列順序。 更改列順序的唯一方法是重新創建表,或者添加列並旋轉數據直到達到所需的布局。
這很弱,但在他們的辯護中,在標准 SQL 中,也沒有重新定位列的解決方案。 支持更改列序數位置的數據庫品牌正在定義 SQL 語法的擴展。
我想到了另一個想法:您可以定義一個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;
這篇文章很舊,可能已經解決了,但我遇到了同樣的問題。 我通過創建指定新列順序的原始表的視圖來解決它。
從這里我可以使用視圖或從視圖創建一個新表。
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
重命名或刪除原始表並將新表的名稱設置為舊表。
一個,雖然當列順序必須絕對改變並且外鍵正在使用時重新排列列是一個笨拙的選擇,但是首先用數據轉儲整個數據庫,然后只轉儲模式( 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;
將“新”名稱更改為“舊” ALTER TABLE new RENAME TO old;
你就完成了。
我正在對很多表進行重新排序,並且不想一遍又一遍地編寫相同的查詢,因此我制作了一個腳本來為我完成所有工作。 本質上,它:
pg_dump
獲取建表 SQLpg_dump
查詢以創建一個重新排序的包含數據的表可以通過運行以下簡單命令來使用它:
./reorder.py -n schema -d database table \
first_col second_col ... penultimate_col ultimate_col --migrate
它打印出 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
第 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 步:現在我們可以刪除視圖、刪除源表並以舊名稱重命名新表。 騙局成功結束。
有一些解決方法可以使其成為可能:
重新創建整個表
在當前表中創建新列
創建視圖
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.