Est-il possible de changer l'ordre naturel des colonnes dans Postgres?

StackOverflow https://stackoverflow.com/questions/126430

  •  02-07-2019
  •  | 
  •  

Question

Est-il possible de modifier l'ordre naturel des colonnes dans Postgres 8.1?

Je sais que vous ne devriez pas vous fier à l'ordre des colonnes - ce n'est pas essentiel à ce que je fais - je n'ai besoin que de cela pour que certains éléments générés automatiquement soient générés de manière plus efficace. agréable, de sorte que l’ordre des champs soit identique, de pgadmin à l’arrière-plan et jusqu’au début.

Était-ce utile?

La solution

Vous pouvez en fait changer directement l'ordre des colonnes, mais je le recommande à peine, et vous devriez faire très attention si vous décidez de le faire.

par exemple.

# 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)

Maintenant, pour le plus difficile, vous devez vous connecter à votre base de données à l'aide de l'utilisateur postgres afin de pouvoir modifier les tables système.

# 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 est une colonne unique. Vous devez donc utiliser une valeur temporaire lorsque vous modifiez les numéros de colonne en tant que tels:

# 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)

Encore une fois, comme il s’agit de jouer avec les tables du système de base de données, soyez extrêmement prudent si vous estimez que vous en avez vraiment besoin.

Cela fonctionne à partir de postgres 8.3, avec les versions précédentes, votre kilométrage peut varier.

Autres conseils

Si votre base de données n'est pas très grande et que vous pouvez vous permettre un temps d'arrêt, vous pouvez:

  1. Désactiver l'accès en écriture à la base de données
    Ceci est essentiel car sinon tout changement après le début du point suivant sera perdu
  2. pg_dump --create --column-inserts nom de la base de données > databasename.pgdump.sql
  3. Modifiez une instruction CREATE TABLE appropriée dans databasename.pgdump.sql

    Si le fichier est trop volumineux pour votre éditeur, divisez-le simplement à l'aide de la commande split , modifiez-le, puis réassemblez-le à l'aide de cat
  4. supprimer le nom de la base de données de la base de données
    Vous avez une sauvegarde récente, juste au cas où?
  5. psql --single-transaction -f nom_base_données.pgdump.sql
    Si vous n'utilisez pas - transaction unique , le processus sera très lent

Si vous utilisez des objets dits de grande taille, assurez-vous qu’ils sont inclus dans le vidage. Je ne sais pas s'ils sont par défaut en 8.1.

J'ai posé cette question dans pgsql-admin en 2007. Tom Lane lui-même a déclaré qu'il était pratiquement impossible de modifier l'ordre dans les catalogues.

Clarification: pour les utilisateurs, avec les outils actuels. Ne veut pas dire, cela ne pourrait pas être mis en œuvre. OMI, il devrait être.
Toujours vrai pour Postgres 11.

Comme les autres réponses mentionnées, vous ne pouvez pas modifier l'ordre des colonnes, cela dépend de postgres. Vous pouvez (et devriez!) Résoudre votre problème avec une vue. Pour les besoins de votre requête de création de rapport, cela ressemblera à une table. Quelque chose comme:

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

Spécifier l'ordre des colonnes dans la requête est la seule manière fiable (et saine) . Cela dit, vous pouvez généralement obtenir un ordre différent en modifiant le tableau, comme indiqué dans l'exemple ci-dessous, car les colonnes sont généralement renvoyées (dans de telles conditions, dans l'ordre dans lequel elles ont été ajoutées.

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=#

Malheureusement non. L'ordre des colonnes dépend entièrement de Postgres.

Vous pouvez obtenir l'ordre des colonnes souhaité en créant un nouveau tableau et en sélectionnant les colonnes de l'ancien tableau dans l'ordre de votre choix:

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

Notez que cela copie uniquement les données, pas les modificateurs, les contraintes, les index, etc.

Une fois la nouvelle table modifiée à votre guise, supprimez l'original et modifiez le nom du nouveau:

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

Je veux la même chose. Oui, commandez-le maintenant, mais cela ne fait que me frotter:)

Ce que je fais pour le résoudre est le suivant.

Cette méthode vous permettra de conserver les données existantes,

.
  1. Créez une nouvelle version de la table en utilisant l'ordre que je veux, en utilisant un nom temporaire.
  2. Insérez toutes les données de la table existante dans cette nouvelle table.
  3. Supprimez l'ancienne table.
  4. Renommez la nouvelle table en "Propre". à partir de "nom temporaire".
  5. Ajoutez de nouveau tous les index que vous aviez précédemment.
  6. Réinitialiser la séquence d'ID pour les incréments de clé primaire.

Ordre actuel des tables:

id, name, email

1. Créez une nouvelle version de la table en utilisant l'ordre que je veux, en utilisant un nom temporaire.

Dans cet exemple, je souhaite que email soit avant nom .

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

2. Insérez toutes les données de la table existante dans cette nouvelle table.

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

3. Supprimez l'ancienne table.

DROP TABLE mytable;

4. Renommez la nouvelle table en " nom propre " à partir de "nom temporaire".

ALTER TABLE mytable_tmp RENAME TO mytable;

5. Rajoutez tous les index que vous aviez précédemment.

CREATE INDEX ...

6. Réinitialiser la séquence d'ID pour les incréments de clé primaire.

SELECT setval('public.mytable_id_seq', max(id)) FROM mytable;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top