PostgreSQL 22030 오류 원인과 해결 방법 완벽 가이드

22030
2026년 06월 16일 | DBMS Error 가이드

이 글에서 다루는 내용

22030 에러의 원인 분석, 해결 SQL, 예방 방법을 실무 관점에서 정리합니다.

22030 duplicate json object key value 는?

PostgreSQL 에러 코드 22030은 duplicate json object key value로, JSON 객체 내에서 동일한 키(key)가 두 번 이상 사용될 때 발생하는 에러입니다. JSON 표준(RFC 7159)에서는 객체 내 키의 중복을 허용하지 않도록 권고하고 있으며, PostgreSQL의 엄격한 JSON 파싱 모드에서는 이를 오류로 처리합니다. 주로 json_object(), jsonb_build_object() 함수 사용 시 또는 외부 시스템에서 생성된 JSON 데이터를 PostgreSQL에 삽입할 때 자주 마주치게 됩니다.


주요 발생 원인

1. jsonb_build_object() 또는 json_build_object() 함수에 중복 키 전달

가장 흔한 원인으로, 개발자가 동적으로 JSON을 구성하는 과정에서 실수로 동일한 키를 두 번 이상 인자로 넘기는 경우입니다. 특히 여러 컬럼을 동적으로 조합할 때 중복이 발생하기 쉽고, jsonb 타입은 내부적으로 중복 키를 허용하지 않기 때문에 즉시 에러를 발생시킵니다.

2. 외부 시스템 또는 애플리케이션에서 생성된 중복 키 포함 JSON 문자열 삽입

외부 API, 레거시 시스템, 또는 잘못 구현된 클라이언트에서 생성된 JSON 문자열에 중복 키가 포함된 채로 PostgreSQL jsonb 컬럼에 저장을 시도할 때 발생합니다. json 타입은 중복 키를 허용하지만 jsonb 타입은 저장 시 중복 키를 제거하거나 에러를 발생시키는 차이가 있습니다. 이 경우 데이터 파이프라인 전체를 점검해야 할 필요가 있습니다.

3. SQL 쿼리 내 집계 또는 조인 결과에서 중복 키 발생

json_object_agg() 함수를 사용할 때 집계 대상 데이터에 동일한 키 값이 존재하는 경우 22030 에러가 발생합니다. 예를 들어 GROUP BY 없이 또는 데이터 정제 없이 중복된 레코드를 집계하면, 동일한 키가 JSON 객체에 두 번 들어가려는 시도가 생깁니다.


해결 방법

원인 1: jsonb_build_object() 중복 키 제거

중복 키를 직접 제거하거나, 키 이름을 명확하게 다르게 지정하십시오.

-- 에러 발생 예시
SELECT jsonb_build_object('name', 'Alice', 'age', 30, 'name', 'Bob');
-- ERROR:  duplicate key value violates unique constraint (22030)

-- 해결: 중복 키 제거
SELECT jsonb_build_object('name', 'Alice', 'age', 30);

-- 또는 키를 명시적으로 다르게 지정
SELECT jsonb_build_object('first_name', 'Alice', 'last_name', 'Bob', 'age', 30);

원인 2: 외부 JSON 문자열의 중복 키 처리

json 타입으로 먼저 받은 후 중복을 제거하는 방식을 활용하거나, 애플리케이션 레이어에서 전처리하세요.

-- json 타입은 중복 키를 허용 (마지막 값 또는 첫 번째 값 유지)
SELECT '{"name": "Alice", "name": "Bob"}'::json;
-- 정상 동작 (json 타입은 허용)

-- jsonb로 변환 시 중복 키는 마지막 값으로 자동 병합됨
SELECT '{"name": "Alice", "name": "Bob"}'::json::jsonb;
-- 결과: {"name": "Bob"}

-- 외부 데이터를 jsonb 컬럼에 안전하게 삽입하는 방법
INSERT INTO user_profiles (data)
VALUES ('{"name": "Alice", "name": "Bob"}'::json::jsonb);
-- json → jsonb 캐스팅으로 중복 키 자동 처리

-- 중복 키 검증 함수 생성 (삽입 전 검사용)
CREATE OR REPLACE FUNCTION is_valid_jsonb(input TEXT)
RETURNS BOOLEAN AS $$
BEGIN
    PERFORM input::jsonb;
    RETURN TRUE;
EXCEPTION WHEN OTHERS THEN
    RETURN FALSE;
END;
$$ LANGUAGE plpgsql;

SELECT is_valid_jsonb('{"name": "Alice", "name": "Bob"}');

원인 3: json_object_agg() 사용 시 중복 키 제거

집계 전에 DISTINCT 또는 서브쿼리를 활용해 중복 데이터를 제거하세요.

-- 에러 발생 예시: 중복 키가 있는 데이터 집계
CREATE TABLE product_tags (product_id INT, tag_key TEXT, tag_value TEXT);
INSERT INTO product_tags VALUES (1, 'color', 'red'), (1, 'color', 'blue'), (1, 'size', 'L');

-- 중복 키로 인한 에러 발생
SELECT json_object_agg(tag_key, tag_value)
FROM product_tags
WHERE product_id = 1;
-- ERROR: duplicate key value "color"

-- 해결 방법 1: DISTINCT ON으로 중복 제거
SELECT json_object_agg(tag_key, tag_value)
FROM (
    SELECT DISTINCT ON (tag_key) tag_key, tag_value
    FROM product_tags
    WHERE product_id = 1
    ORDER BY tag_key, tag_value
) deduped;

-- 해결 방법 2: 집계 함수로 중복 키의 값을 병합
SELECT json_object_agg(tag_key, tag_values)
FROM (
    SELECT tag_key, string_agg(tag_value, ',') AS tag_values
    FROM product_tags
    WHERE product_id = 1
    GROUP BY tag_key
) grouped;

예방 방법

1. jsonb 컬럼에 CHECK 제약 조건과 입력 유효성 검사 함수 적용

데이터가 테이블에 삽입되기 전에 애플리케이션 레이어와 데이터베이스 레이어 양쪽에서 JSON 구조를 검증하는 습관을 들이십시오. 특히 외부 데이터를 수신하는 파이프라인에서는 json → jsonb 캐스팅을 활용하거나, 트리거를 통해 중복 키 포함 데이터를 사전에 차단하는 구조를 갖추는 것이 좋습니다.

-- 트리거를 활용한 JSON 유효성 검사 예시
CREATE OR REPLACE FUNCTION validate_json_keys()
RETURNS TRIGGER AS $$
BEGIN
    -- json → jsonb 변환으로 중복 키 자동 정리 후 저장
    NEW.data = NEW.data::text::jsonb;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trg_validate_json
BEFORE INSERT OR UPDATE ON user_profiles
FOR EACH ROW EXECUTE FUNCTION validate_json_keys();

2. 동적 JSON 생성 시 키 목록 사전 중복 검사 로직 구현

jsonb_build_object()json_object_agg()를 사용하는 쿼리에서는 반드시 키 목록에 중복이 없는지 확인하는 서브쿼리 또는 CTE를 선행하여 작성하십시오. 코드 리뷰 단계에서도 JSON 키 중복 여부를 체크리스트 항목으로 포함시켜 사전에 방지하는 문화를 만드는 것이 장기적으로 가장 효과적인 예방책입니다.


관련 에러

  • 22032 (invalid_json_text): JSON 문자열 자체가 문법적으로 올바르지 않을 때 발생하며, 22030과 함께 JSON 처리 시 가장 자주 마주치는 에러입니다.
  • 23505 (unique_violation): JSONB 인덱스가 설정된 컬럼에서 중복 값 삽입 시 발생하며, JSON 키 중복과는 별개이지만 유사한 맥락에서 발생할 수 있습니다.
  • 42804 (datatype_mismatch): JSON 값을 잘못된 타입 컬럼에 삽입하려 할 때 발생하며, JSON 관련 작업에서 함께 주의해야 할 에러입니다.

DBMS 에러 코드 시리즈

주요 DBMS error code를 정리하는 시리즈입니다.
블로그 홈에서 다른 에러도 확인하세요.

본 포스트는 AI가 생성한 기술 가이드입니다. 운영 환경 적용 전 충분한 검토를 권장합니다.

댓글 남기기