webentwicklung-frage-antwort-db.com.de

Wie lösche ich einen Aufzählungswert in Postgres?

Wie lösche ich einen Aufzählungstypwert, den ich in postgresql erstellt habe? 

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

Z.B. Ich möchte moderator aus der Liste entfernen.

Ich kann anscheinend nichts in den Dokumenten finden. 

Ich verwende Postgresql 9.3.4.

56
Amjith

Sie löschen (löschen) Aufzählungstypen wie jeden anderen Typ mit DROP TYPE :

DROP TYPE admin_level1;

Ist es möglich, dass Sie tatsächlich fragen, wie Sie einen einzelnen Wert aus einem Aufzählungstyp entfernenWenn ja, kannst du nicht. Es wird nicht unterstützt :

Obwohl enum-Typen hauptsächlich für statische Wertesätze vorgesehen sind, können Sie einem vorhandenen Aufzählungstyp neue Werte hinzufügen und Werte umbenennen (siehe ALTER TYPE). Vorhandene Werte können nicht aus einem Aufzählungstyp entfernt werden, und die Sortierreihenfolge dieser Werte kann nicht geändert werden, ohne dass der Aufzählungstyp gelöscht und erneut erstellt wird.

Sie müssen einen neuen Typ ohne den Wert erstellen, alle vorhandenen Verwendungen des alten Typs in den neuen Typ konvertieren und dann den alten Typ löschen.

Z.B.

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

Wenn Sie ein Element des Aufzählungstyps löschen möchten, müssen Sie die Systemtabelle von PostgreSQL verwenden. 

Mit diesem Befehl können Sie alle Elementtypen anzeigen.

SELECT * FROM pg_enum;

Überprüfen Sie dann, ob der Wert eindeutig ist. Um die Eindeutigkeit während der Entfernung von rekoru zu erhöhen, muss zusätzlich zu „enumlabel“ „enumtypid“ übergeben werden.

Dieser Befehl entfernt den Eintrag im Aufzählungstyp, wobei "unique" Ihr Wert ist.

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

NOTE Das Beispiel, das ich beschrieben habe, muss verwendet werden, wenn wir zufällig einen neuen Wert zum Aufzählungstyp hinzufügen und ihn jedoch nirgendwo in der Datenbank verwendet haben.

23
elcudro

Sehr gut hier geschrieben:

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

den vorhandenen Typ umbenennen

ALTER TYPE status_enum RENAME TO status_enum_old;

den neuen Typ erstellen

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

die Spalten aktualisieren, um den neuen Typ zu verwenden

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

entferne den alten Typ

DROP TYPE status_enum_old;
14
dnaik

Für diejenigen, die die Aufzählungswerte ändern möchten, scheint die Neuformulierung die einzige praktikable und sichere Lösung zu sein.

Sie besteht darin, die Enumenspalte vorübergehend in ein Stringformat zu konvertieren, die Enumeration neu zu erstellen und dann die Stringspalte wieder in den Enummentyp zu konvertieren.

Hier ist ein Beispiel:

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

Verwenden Sie die folgende Abfrage, um den ENUM-Wert aus dem Postgresql-Typ zu löschen

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

Nur Infos zum Typ und Wert 

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

Sie sollten vorhandene Werte in andere ändern. Wenn Sie einen neuen Wert hinzufügen müssen, verwenden Sie:

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

Aktualisieren Sie vor dem Löschen den Typwert auf einen neuen Typwert oder einen vorhandenen Wert.

5
Somnath Muluk

wenn Ihr Dataset nicht so groß ist, können Sie mit --column-inserts einen Dump mit einem Texteditor bearbeiten, den Wert entfernen und den Dump erneut importieren

2
sherpya

Der programmatische Weg dazu ist wie folgt. Die gleichen allgemeinen Schritte wie angegebenIn https://stackoverflow.com/a/47305844/629272 sind angemessen, aber diese sind __ ). my_type, my_type_old und value_to_delete sollten natürlich entsprechend geändert werden.

  1. Benennen Sie Ihren Typ um.

    ALTER TYPE my_type RENAME TO my_type_old;
    
  2. Erstellen Sie einen neuen Typ mit den Werten Ihres alten Typs, ausgenommen denjenigen Sie möchten löschen.

    DO $$
    BEGIN
        EXECUTE format(
            'CREATE TYPE my_type AS ENUM (%s)',
            (
                SELECT string_agg(quote_literal(value), ',')
                FROM unnest(enum_range(NULL::my_type_old)) value
                WHERE value <> 'value_to_delete'
            )
        );
    END $$;
    
  3. Ändern Sie alle vorhandenen Spalten, die den alten Typ verwenden, um den neuen zu verwenden.

    DO $$
    DECLARE
        column_data record;
        table_name varchar(255);
        column_name varchar(255);
    BEGIN
        FOR column_data IN
            SELECT cols.table_name, cols.column_name
                FROM information_schema.columns cols
                WHERE udt_name = 'my_type_old'
        LOOP
            table_name := column_data.table_name;
            column_name := column_data.column_name;
            EXECUTE format(
                '
                    ALTER TABLE %s
                    ALTER COLUMN %s
                    TYPE my_type
                    USING %s::text::my_type;
                ',
                table_name, column_name, column_name
            );
        END LOOP;
    END $$;
    
  4. Löschen Sie den alten Typ.

    DROP TYPE my_type_old;
    
0
Californian