[postgresql] Postgres에서 열거 형 값을 삭제하는 방법은 무엇입니까?
postgresql에서 생성 한 열거 형 값을 어떻게 삭제합니까?
create type admin_level1 as enum('classifier', 'moderator', 'god');
예 : moderator
목록에서 제거하고 싶습니다 .
문서에서 아무것도 찾을 수없는 것 같습니다.
Postgresql 9.3.4를 사용하고 있습니다.
답변
다른 유형과 마찬가지로 열거 형 유형을 삭제 (삭제)합니다 DROP TYPE
.
DROP TYPE admin_level1;
열거 형 유형에서 개별 값 을 제거하는 방법에 대해 실제로 묻는 것이 가능 합니까? 그렇다면 할 수 없습니다. 지원되지 않습니다 .
enum
형식은 주로 정적 값 집합을위한 것이지만 기존 열거 형 형식에 새 값을 추가하고 값의 이름을 바꾸는 기능이 지원됩니다 (참조ALTER TYPE
). 기존 값은 열거 형 유형에서 제거 할 수 없으며 열거 형 유형을 삭제하고 다시 생성하지 않고는 이러한 값의 정렬 순서를 변경할 수 없습니다.
값없이 새 유형을 작성하고 이전 유형의 모든 기존 사용을 새 유형을 사용하도록 변환 한 다음 이전 유형을 삭제해야합니다.
예
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;
답변
여기에 아주 잘 쓰여졌습니다.
http://blog.yo1.dog/updating-enum-values-in-postgresql-the-safe-and-easy-way/
기존 유형 이름 바꾸기
ALTER TYPE status_enum RENAME TO status_enum_old;
새로운 유형 만들기
CREATE TYPE status_enum AS ENUM('queued', 'running', 'done');
새 유형을 사용하도록 열 업데이트
ALTER TABLE job ALTER COLUMN job_status TYPE status_enum USING job_status::text::status_enum;
이전 유형 제거
DROP TYPE status_enum_old;
답변
enum 유형의 항목을 삭제하려면 PostgreSQL의 시스템 테이블에서 작업해야합니다.
이 명령을 사용하면 모든 항목 열거 유형을 표시 할 수 있습니다.
SELECT * FROM pg_enum;
그런 다음 검색된 값이 고유한지 확인하십시오. rekoru를 제거하는 동안 고유성을 높이려면 ‘enumlabel’외에도 ‘enumtypid’를 전달해야합니다.
이 명령은 enum 유형의 항목을 제거합니다. 여기서 ‘unique’는 값입니다.
pg_enum에서 삭제 en WHERE en.enumtypid = 124 AND en.enumlabel = ‘unique’;
참고
내가 설명한 예제는 우연히 열거 형 유형에 새 값을 추가했지만 데이터베이스의 어느 곳에서도 사용하지 않았을 때 사용해야합니다.
답변
열거 형 값을 수정하려는 사람들에게는이를 다시 만드는 것이 실행 가능하고 안전한 유일한 솔루션 인 것 같습니다.
열거 형 열을 문자열 형식으로 일시적으로 변환하고, 열거 형을 다시 만든 다음 문자열 열을 다시 열거 형 유형으로 다시 변환하는 것으로 구성됩니다.
다음은 예입니다.
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');
답변
Postgresql 유형에서 ENUM 값을 삭제하려면 다음 쿼리를 사용하십시오.
DELETE FROM pg_enum
WHERE enumlabel = 'moderator'
AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = 'admin_level1');
유형 및 가치에 대한 정보
DELETE FROM pg_enum
WHERE enumlabel = 'ENUM_VALUE'
AND enumtypid = ( SELECT oid FROM pg_type WHERE typname = 'ENUM_TYPE')
기존 값을 다른 값으로 변경해야합니다. 이를 위해 새 값을 추가해야하는 경우 다음을 사용하십시오.
ALTER TYPE **ENUM_TYPE** ADD VALUE '**ENUM_VALUE2**';
삭제하기 전에 유형 값을 새 유형 값 또는 기존 값으로 업데이트하십시오.
답변
이를 수행하는 프로그래밍 방식은 다음과 같습니다. https://stackoverflow.com/a/47305844/629272에 제공된 것과 동일한 일반 단계 가 적절하지만 내 목적에 맞는 것보다 수동입니다 (Alembic 다운 마이그레이션 작성). my_type
, my_type_old
그리고 value_to_delete
, 물론, 적절하게 변경해야합니다.
-
유형의 이름을 바꿉니다.
ALTER TYPE my_type RENAME TO my_type_old;
-
삭제할 유형을 제외하고 이전 유형의 값으로 새 유형을 만듭니다.
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 $$;
-
새 열을 사용하려면 이전 유형을 사용하는 모든 기존 열을 변경하십시오.
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 $$;
-
이전 유형을 삭제하십시오.
DROP TYPE my_type_old;
답변
데이터 세트가 너무 크지 않은 경우 --column-inserts
텍스트 편집기로 덤프를 편집하여 덤프하고 값을 제거하고 덤프를 다시 가져올 수 있습니다.