Logo
KB/backend/postgresql duplicate key value violates unique constrain 에러 해결하기

postgresql duplicate key value violates unique constrain 에러 해결하기

·3 min read·backend

배경

postgresql db를 사용 중, backend에서 orm으로 create 명령을 실행할 때 문제가 발생했습니다. 바로 알아채지 못하고 검색이 필요했어서 앞으로 기억하기 위해 정리합니다.

문제

pg table에 row를 insert 하려고 할 때 duplicate key value violates unique constrain PK_324238724 에러가 발생합니다. 이는 쉽게 이야기하면, 내가 row를 하나 더 생성하려고 할 때, table 이 자동으로 부여하려고 하는 key가 중복된다는 뜻입니다. 다행히 이 문제를 쉽게 유추한 것은 위 테이블의 row를 제가 직접 조작한 적이 있었기 때문에, PK가 중복되는 이유는 내부의 key가 중복될 것이라 판단했기 때문입니다. 구글링을 해본 결과 역시 가장 확률이 높았고 postgresql의 sequence manipulation function을 실행해서 이 문제를 해결할 수 있었습니다.

Sequence Manipulation Functions

Sequences란?

Sequence objects are special single-row tables created with CREATE SEQUENCE.

9.17. Sequence Manipulation Functions 공식 문서

해결

  1. key 이름을 찾습니다.

    
    -- Sequence and defined type
    CREATE SEQUENCE IF NOT EXISTS table_id_seq;
    
    -- Table Definition
    CREATE TABLE "public"."table" (
        "id" int4 NOT NULL DEFAULT nextval('table_id_seq'::regclass),
        "slug" varchar NOT NULL DEFAULT 'noname'::character varying,
        "description" text,
        "create_datetime" timestamp NOT NULL DEFAULT now(),
        PRIMARY KEY ("id")
    );
    

    이런 식으로 create query를 조회해 보시면 table_id_seq라는 key를 알 수 있습니다.

  2. select lastval() from 테이블 이름; 을 실행하면 현재 table에 설정된 key의 값을 알 수 있습니다. 보통 에러가 나는 경우에는 table에 특수한 조작으로 row를 이전에 insert해서 table 내부 table_id_seq값이 max(id)보다 작아서 이미 해당 id의 row가 존재함을 알 수 있습니다.

  3. select setval('table_id_seq', (select max(id) from table)); 쿼리를 실행해 키의 최대값을 재설정합니다.

  4. 이후에 아까 실행하려던 insert 쿼리를 생성하면 정상적으로 실행되는 것을 알 수 있습니다.

끝!!!

앞으로 할 일

그냥 typeorm에서는 @PrimaryGeneratedColumn() 로 선언한 컬럼이 실제로는 Sequence를 생성한다는 사실을 알았습니다. orm에 너무 의존하다 보니 이렇게 에러를 만나게 되면 해결하기 쉽지 않은데요, 이렇게 만날 때마다 공부해 놓으면 될 것 같습니다.

● KBbackend·2023-06-01-pg-duplicate-key-voilates3 min read