postgresql - tutoriales - ¿Cómo eliminar un valor de tipo de enumeración en postgres?
tutoriales de postgres (8)
Elimina (suelta) tipos de enumeración como cualquier otro tipo, con DROP TYPE
:
DROP TYPE admin_level1;
¿Es posible que realmente esté preguntando cómo eliminar un valor individual de un tipo de enumeración ? Si es así, no puedes. No es compatible :
Aunque los tipos de
enum
están destinados principalmente a conjuntos de valores estáticos, hay soporte para agregar nuevos valores a un tipo de enumeración existente y para cambiar el nombre de los valores (consulteALTER TYPE
). Los valores existentes no se pueden eliminar de un tipo de enumeración, ni se puede cambiar el orden de clasificación de dichos valores, sin añadir y recrear el tipo de enumeración.
Debe crear un nuevo tipo sin el valor, convertir todos los usos existentes del tipo anterior para usar el nuevo tipo y luego eliminar el tipo anterior.
P.ej
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;
¿Cómo elimino un valor de tipo de enumeración que creé en postgresql?
create type admin_level1 as enum(''classifier'', ''moderator'', ''god'');
Por ejemplo, quiero eliminar el moderator
de la lista.
Parece que no puedo encontrar nada en los documentos.
Estoy usando Postgresql 9.3.4.
En pocas palabras, no es posible eliminar un valor individual de ENUM, la única solución posible es DROP y recrear ENUM con los valores necesarios.
La forma programática de hacer esto es la siguiente. Los mismos pasos generales que se indican en https://.com/a/47305844/629272 son apropiados, pero son más manuales que los que tienen sentido para mis propósitos (escribir una migración de cadáveres). my_type
, my_type_old
, y value_to_delete
, deben, por supuesto, cambiarse según corresponda.
Renombra tu tipo.
ALTER TYPE my_type RENAME TO my_type_old;
Cree un nuevo tipo con los valores de su tipo anterior, excluyendo el que desea eliminar.
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 $$;
Cambie todas las columnas existentes que usan el tipo anterior para usar la nueva.
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 $$;
Eliminar el tipo antiguo.
DROP TYPE my_type_old;
Muy bien escrito aquí:
http://blog.yo1.dog/updating-enum-values-in-postgresql-the-safe-and-easy-way/
renombrar el tipo existente
ALTER TYPE status_enum RENAME TO status_enum_old;
crear el nuevo tipo
CREATE TYPE status_enum AS ENUM(''queued'', ''running'', ''done'');
Actualizar las columnas para usar el nuevo tipo.
ALTER TABLE job ALTER COLUMN job_status TYPE status_enum USING job_status::text::status_enum;
quitar el tipo antiguo
DROP TYPE status_enum_old;
Para aquellos que desean modificar los valores de enumeración, recrearlo parece ser la única solución viable y segura.
Consiste en convertir temporalmente la columna de enumeración a un formato de cadena, volver a crear la enumeración y luego volver a convertir la columna de cadena en el tipo de enumeración.
Aquí hay un ejemplo:
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'');
Si desea eliminar un elemento de tipo de enumeración, debe operar en la tabla del sistema de PostgreSQL.
Con este comando, puede mostrar todos los elementos enum tipo.
SELECT * FROM pg_enum;
A continuación, compruebe que el valor buscado es único. Para aumentar la singularidad durante la eliminación de rekoru, debe pasarse ''enumtypid'' además de ''enumlabel''.
Este comando elimina la entrada en el tipo de enumeración, donde "único" es su valor.
ELIMINAR DE pg_enum es DONDE en.enumtypid = 124 Y en.enumlabel = ''único'';
NOTA El ejemplo que describí debe usarse, cuando por casualidad agregamos un nuevo valor al tipo de enumeración y, sin embargo, no lo hemos utilizado en ninguna parte de la base de datos.
Si su conjunto de datos no es tan grande, puede volcar con --column-inserts
editar el volcado con un editor de texto, eliminar el valor y volver a importar el volcado
Utilice la siguiente consulta para eliminar el valor ENUM del tipo Postgresql
DELETE FROM pg_enum
WHERE enumlabel = ''moderator''
AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = ''admin_level1'');
Sólo información para lo que es tipo y lo que es valor
DELETE FROM pg_enum
WHERE enumlabel = ''ENUM_VALUE''
AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = ''ENUM_TYPE'')
Debes cambiar los valores existentes a otros. Para eso, si necesita agregar un nuevo valor, entonces use:
ALTER TYPE **ENUM_TYPE** ADD VALUE ''**ENUM_VALUE2**'';
Antes de eliminar, actualice el valor de tipo a un nuevo valor de tipo o valor existente.