Pergunta

É possível alterar a ordem natural das colunas no Postgres 8.1?

Eu sei que você não deve confiar em ordem de coluna - não é essencial para o que estou fazendo - eu só preciso fazer algumas coisas gerado automaticamente sair de uma forma que é mais agradável, de modo que a ordem dos campos corresponde todo o caminho de pgadmin até o final para trás e para o front-end.

Foi útil?

Solução

Você pode realmente apenas em linha reta até alterar a ordem das colunas, mas eu quase não recomendo-o, e você deve ter muito cuidado se você decidir fazê-lo.

por exemplo.

# CREATE TABLE test (a int, b int, c int);
# INSERT INTO test VALUES (1,2,3);
# SELECT * FROM test;
 a | b | c 
---+---+---
 1 | 2 | 3
(1 row)

Agora, a pouco complicado, você precisa se conectar ao seu banco de dados usando o usuário postgres para que você possa modificar as tabelas do sistema.

# SELECT relname, relfilenode FROM pg_class WHERE relname='test';
 relname | relfilenode 
---------+-------------
 test_t  |       27666
(1 row)

# SELECT attrelid, attname, attnum FROM pg_attribute WHERE attrelid=27666;
 attrelid | attname  | attnum 
----------+----------+--------
    27666 | tableoid |     -7
    27666 | cmax     |     -6
    27666 | xmax     |     -5
    27666 | cmin     |     -4
    27666 | xmin     |     -3
    27666 | ctid     |     -1
    27666 | b        |      1
    27666 | a        |      2
    27666 | c        |      3
(9 rows)

attnum é uma coluna única, então você precisa usar um valor temporário quando você está modificando os números das colunas como tal:

# UPDATE pg_attribute SET attnum=4 WHERE attname='a' AND attrelid=27666;
UPDATE 1
# UPDATE pg_attribute SET attnum=1 WHERE attname='b' AND attrelid=27666;
UPDATE 1
# UPDATE pg_attribute SET attnum=2 WHERE attname='a' AND attrelid=27666;
UPDATE 1

# SELECT * FROM test;
 b | a | c 
---+---+---
 1 | 2 | 3
(1 row)

Mais uma vez, porque isso é brincar com as tabelas do sistema de banco de dados, tenha extremo cuidado se você sentir que você realmente precisa para fazer isso.

Esse é um trabalho a partir de Postgres 8.3, com as versões anteriores, sua milhagem pode variar.

Outras dicas

Se o seu banco de dados não é muito grande e você pode pagar algum tempo de inatividade, em seguida, você pode:

  1. acesso de gravação Desativar para o banco de dados
    este é essencial como de outra forma quaisquer alterações depois de iniciar o próximo ponto será perdido
  2. pg_dump --create --column-inserts databasename > databasename.pgdump.sql
  3. Editar declaração apropriate CREATE TABLE em databasename.pgdump.sql
    Se o arquivo é grande demais para o seu editor apenas dividi-lo usando o comando split, editar, em seguida, montar de volta usando cat
  4. drop database databasename
    Você tem um backup recente, apenas no caso, não é?
  5. psql --single-transaction -f databasename.pgdump.sql
    Se você não usar --single-transaction será muito lento

Se você usar os chamados objetos grandes certificar-se que estão incluídas no despejo. Eu não tenho certeza se eles são por padrão no 8.1.

Eu tenho feito essa pergunta em pgsql-admin em 2007. Tom Lane, se declarou praticamente inviável para alterar a ordem nos catálogos.

Esclarecimento: para os usuários, com as actuais ferramentas. não significa, não poderia ser implementado. IMO, que deveria ser.
Ainda verdade para Postgres 11.

Como as outras respostas mencionado, você não pode alterar a ordem das colunas, que é até postgres. Você pode (e deve!) Resolver o seu problema com uma vista. Para efeitos da sua consulta de relatórios, ele vai olhar apenas como uma mesa. Algo como:

create view my_view as
  select * from my_table
  order by some_col;

Especificando a ordem das colunas na consulta é a única maneira confiável (e são) . Dito isto, você normalmente pode obter uma ordem diferente, alterando a tabela como mostrado no exemplo abaixo como as colunas são normalmente (não garantido para ser) retornado na ordem em que foram adicionados à tabela.

postgres=# create table a(a int, b int, c int);
CREATE TABLE
postgres=# insert into a values (1,2,3);
INSERT 0 1
postgres=# select * from a;
 a | b | c
---+---+---
 1 | 2 | 3
(1 row)

postgres=# alter table a add column a2 int;
ALTER TABLE
postgres=# select * from a;
 a | b | c | a2
---+---+---+----
 1 | 2 | 3 |
(1 row)

postgres=# update a set a2 = a;
UPDATE 1
postgres=# alter table a drop column a;
ALTER TABLE
postgres=# alter table a rename column a2 to a;
ALTER TABLE
postgres=# select * from a;
 b | c | a
---+---+---
 2 | 3 | 1
(1 row)

postgres=#

Infelizmente, não, não é. a ordem das colunas é inteiramente até Postgres.

Você pode obter a ordem das colunas que você quer através da criação de uma nova tabela e selecionando as colunas da tabela antiga na ordem em que você quer que eles presentes:

CREATE TABLE test_new AS SELECT b, c, a FROM test;
SELECT * from test_new;
 b | c | a 
---+---+---
 2 | 3 | 1
(1 row)

Note-se que esta copia dados só, não modificadores, os constrangimentos, os índices, etc ..

Uma vez que a nova tabela é modificado da maneira que quiser, soltar o original e alterar o nome do novo:

BEGIN;
DROP TABLE test;
ALTER TABLE test_new RENAME TO test;
COMMIT;

Eu estou querendo o mesmo. Sim, a ordem agora essencial, mas apenas esfrega-me o caminho errado:)

O que estou fazendo para resolvê-lo é a seguinte.

Este método irá garantir que você mantenha todos os dados existentes,

  1. Criar uma nova versão da tabela usando a ordenação que eu quero, usando um nome temporário.
  2. Inserir todos os dados para que a nova tabela a partir do já existente.
  3. Solte a tabela antiga.
  4. Mudar o nome da nova tabela para o "nome próprio" de "nome temporário".
  5. Re-adicionar os índices que você tinha anteriormente.
  6. seqüência ID Reset por incrementos de chave primária.

ordem de tabela atual:

id, name, email

1. Criar uma nova versão da tabela usando a ordenação que eu quero, usando um nome temporário.

Neste exemplo, eu quero email ser antes name.

CREATE TABLE mytable_tmp
(
  id SERIAL PRIMARY KEY,
  email text,
  name text
);

2. Inserir todos os dados para que a nova tabela a partir do já existente.

INSERT INTO mytable_tmp   --- << new tmp table
(
  id
, email
, name
)
SELECT
  id
, email
, name
FROM mytable;  --- << this is the existing table

3. Largue a tabela antiga.

DROP TABLE mytable;

4. Renomeie a nova tabela para o "nome próprio" de "nome temporário".

ALTER TABLE mytable_tmp RENAME TO mytable;

5. Re-adicionar os índices que você tinha anteriormente.

CREATE INDEX ...

6. sequência ID Reset por incrementos de chave primária.

SELECT setval('public.mytable_id_seq', max(id)) FROM mytable;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top