web-dev-qa-db-ja.com

PostgreSQLデータベーステーブルの列の位置を変更するにはどうすればよいですか?

次のことを試しましたが、失敗しました:

ALTER TABLE person ALTER COLUMN dob POSITION 37;
96
Huuuze

PostgreSQL Wikiの「 列の変更位置 」は次のように述べています。

PostgreSQLは現在、pg_attributeテーブルのattnum列に基づいて列の順序を定義しています。列の順序を変更する唯一の方法は、表を再作成するか、目的のレイアウトに達するまで列を追加してデータを回転させることです。

それはかなり弱いですが、彼らの防御では、標準SQLでは、列を再配置するための解決策もありません。列の順序位置の変更をサポートするデータベースブランドは、SQL構文の拡張を定義しています。

私にはもう1つのアイデアがあります。ベーステーブル内の列の物理的な位置を変更することなく、列の順序を指定するVIEWを定義できます。

91
Bill Karwin

この投稿は古く、おそらく解決されていますが、私は同じ問題を抱えていました。新しい列の順序を指定して元のテーブルのビューを作成することで解決しました。

ここから、ビューを使用するか、ビューから新しいテーブルを作成できます。

 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-または何でも
 SELECT * INTO new_table FROM original_tab_vw 

元のテーブルの名前を変更または削除し、新しいテーブルの名前を古いテーブルに設定します。

25
Ken

1つは、列の順序を絶対に変更する必要があり、外部キーが使用されているときに列を再配置するための扱いにくいオプションではありますが、最初にデータベース全体をデータでダンプし、次にスキーマだけをダンプすることです(pg_dump -s databasename > databasename_schema.sql)。次に、スキーマファイルを編集して、必要に応じて列を再配置し、スキーマからデータベースを再作成し、最後に新しく作成したデータベースにデータを復元します。

19
Ville

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;
16
Allwin

現時点ではできるとは思いません: Postgresql wikiのこの記事 を参照してください。

この記事の3つの回避策は次のとおりです。

  1. テーブルを再作成する
  2. 列を追加してデータを移動する
  3. ビューで違いを非表示にします。
8
Mike Woodhouse

PGAdminでテーブルを開き、下部のSQLペインでSQL Create Tableステートメントをコピーします。次に、クエリツールを開いて貼り付けます。テーブルにデータがある場合は、テーブル名を「new_name」に変更し、そうでない場合は、Drop Table行のコメント「-」を削除します。必要に応じて列の順序を編集します。移動した場合に備えて、最後の列の欠落/余分なコンマに注意してください。新しいSQL Create Tableコマンドを実行します。リフレッシュして...voilà。

設計段階の空のテーブルの場合、この方法は非常に実用的です。

テーブルにデータがある場合、データの列順序も再配置する必要があります。これは簡単です。INSERTを使用して、古いテーブルを新しいバージョンにインポートします。

INSERT INTO new ( c2, c3, c1 ) SELECT * from old;

...ここで、c2c3c1は、新しいテーブルの古いテーブルの列c1c2c3です。この場合、編集した「古い」テーブルに対して「新しい」名前を使用する必要があります、またはデータが失われますに注意してください。列名が多く、長く、複雑な場合、上記と同じ方法を使用して新しいテーブル構造をテキストエディターにコピーし、INSERTステートメントにコピーする前に新しい列リストを作成します。

すべてが正常であることを確認した後、古いテーブルをDROPALTER TABLE new RENAME TO old;を使用して「新しい」名前を「古い」に変更します。

5
marcopolo

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 *にpgを挿入すると、bigint型のinsetad bigserialが作成されます。

ステップ4:ビューをドロップし、ソーステーブルをドロップし、新しいテーブルの名前を古い名前に変更します。トリックは正常に終了しました。

0
Orlov Const