web-dev-qa-db-fra.com

Comment supprimer une valeur de type enum dans postgres?

Comment puis-je supprimer une valeur de type enum créée dans postgresql? 

create type admin_level1 as enum('classifier', 'moderator', 'god');

Par exemple. Je veux supprimer moderator de la liste.

Je n'arrive pas à trouver quoi que ce soit sur la documentation. 

J'utilise Postgresql 9.3.4.

56
Amjith

Vous supprimez (supprimez) les types d’énumération comme tout autre type, avec DROP TYPE :

DROP TYPE admin_level1;

Est-il possible que vous demandiez réellement comment supprimer une valeur individuelle d'un type enum? Si oui, vous ne pouvez pas. Ce n'est pas supporté :

Bien que les types enum soient principalement destinés aux ensembles de valeurs statiques, il est possible d'ajouter de nouvelles valeurs à un type enum existant et de renommer des valeurs (voir ALTER TYPE). Les valeurs existantes ne peuvent pas être supprimées d'un type enum, ni l'ordre de tri de ces valeurs, à moins de supprimer et de recréer le type enum.

Vous devez créer un nouveau type sans la valeur, convertir toutes les utilisations existantes de l'ancien type pour utiliser le nouveau type, puis supprimer l'ancien type.

Par exemple.

CREATE TYPE admin_level1 AS ENUM ('classifier', 'moderator');

CREATE TABLE blah (
    user_id integer primary key,
    power admin_level1 not null
);

INSERT INTO blah(user_id, power) VALUES (1, 'moderator'), (10, 'classifier');

ALTER TYPE admin_level1 ADD VALUE 'god';

INSERT INTO blah(user_id, power) VALUES (42, 'god');

-- .... oops, maybe that was a bad idea

CREATE TYPE admin_level1_new AS ENUM ('classifier', 'moderator');

-- Remove values that won't be compatible with new definition
-- You don't have to delete, you might update instead
DELETE FROM blah WHERE power = 'god';

-- Convert to new type, casting via text representation
ALTER TABLE blah 
  ALTER COLUMN power TYPE admin_level1_new 
    USING (power::text::admin_level1_new);

-- and swap the types
DROP TYPE admin_level1;

ALTER TYPE admin_level1_new RENAME TO admin_level1;
109
Craig Ringer

Si vous souhaitez supprimer un élément de type énumération, vous devez opérer sur la table système de PostgreSQL. 

Avec cette commande, vous pouvez afficher tous les types d’énumération.

SELECT * FROM pg_enum;

Ensuite, vérifiez que la valeur recherchée est unique. Pour augmenter le caractère unique lors de la suppression de rekoru, vous devez indiquer «enumtypid» en plus de «enumlabel».

Cette commande supprime l'entrée de type enum, où "unique" est votre valeur.

DELETE FROM pg_enum en WHERE en.enumtypid = 124 AND en.enumlabel = 'unique';

NOTE L'exemple que j'ai décrit doit être utilisé, lorsque par hasard nous ajoutons une nouvelle valeur au type enum et que nous ne l'avons jamais utilisée dans aucune base de données.

23
elcudro

Très bien écrit ici:

http://blog.yo1.dog/updating-enum-values-in-postgresql-the-safe-and-easy-way/

renommer le type existant

ALTER TYPE status_enum RENAME TO status_enum_old;

crée le nouveau type

CREATE TYPE status_enum AS ENUM('queued', 'running', 'done');

met à jour les colonnes pour utiliser le nouveau type

ALTER TABLE job ALTER COLUMN job_status TYPE status_enum USING job_status::text::status_enum;

supprime l'ancien type

DROP TYPE status_enum_old;
14
dnaik

Pour ceux qui souhaitent modifier les valeurs enum, la recréer semble être la seule solution viable et sûre.

Cela consiste à convertir temporairement la colonne enum en un format de chaîne, à recréer l'énum, ​​puis à reconvertir la colonne de chaîne en type enum.

Voici un exemple:

ALTER TABLE your_schema.your_table ALTER COLUMN your_column TYPE varchar(255);
ALTER TABLE your_schema.your_table ALTER COLUMN your_column SET DEFAULT('your_default_enum_value');
DROP TYPE your_schema.your_enum_name;
CREATE TYPE your_schema.your_enum_name AS ENUM ('enum1', 'enum2', 'enum3');
ALTER TABLE your_schema.your_table ALTER your_column DROP DEFAULT;
ALTER TABLE your_schema.your_table ALTER COLUMN your_column TYPE your_schema.your_enum_name USING your_enum_name::your_schema.your_column;
ALTER TABLE your_schema.your_table ALTER COLUMN your_column SET DEFAULT('your_default_enum_value');
7
sveilleux2

Utilisez la requête suivante pour supprimer la valeur ENUM du type Postgresql

DELETE FROM pg_enum
WHERE enumlabel = 'moderator'
AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = 'admin_level1');

Juste des infos pour savoir quel type et quelle valeur 

DELETE FROM pg_enum
WHERE enumlabel = 'ENUM_VALUE'
AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = 'ENUM_TYPE')

Vous devriez changer les valeurs existantes en autres. Pour cela, si vous devez ajouter une nouvelle valeur, utilisez:

ALTER TYPE **ENUM_TYPE** ADD VALUE '**ENUM_VALUE2**'; 

Avant de supprimer, mettez à jour la valeur du type avec la nouvelle valeur ou la valeur existante.

5
Somnath Muluk

si votre ensemble de données n'est pas si volumineux, vous pouvez dumper avec --column-inserts éditer le dump avec un éditeur de texte, supprimer la valeur et réimporter le dump.

2
sherpya