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

23502
2026년 06월 21일 | DBMS Error 가이드

이 글에서 다루는 내용

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

23502 not null violation 는?

PostgreSQL 에러 코드 23502는 NOT NULL 제약 조건이 설정된 컬럼에 NULL 값을 삽입하거나 업데이트하려 할 때 발생하는 무결성 위반 오류입니다. 데이터베이스 설계 시 특정 컬럼에 반드시 값이 존재해야 한다는 의미로 NOT NULL 제약을 걸어두는데, 애플리케이션 코드나 마이그레이션 스크립트에서 해당 컬럼에 값을 누락하면 이 에러가 발생합니다. 실무에서는 ORM(Object-Relational Mapping) 도구를 사용하는 환경이나 대규모 데이터 마이그레이션 작업 중에 특히 자주 발생하며, 즉각적인 트랜잭션 롤백을 유발하므로 빠른 대처가 필요합니다.


주요 발생 원인

1. INSERT 또는 UPDATE 시 필수 컬럼 값 누락

가장 흔한 원인으로, NOT NULL 제약이 걸린 컬럼에 명시적으로 값을 제공하지 않거나 NULL을 직접 삽입하려 할 때 발생합니다. 특히 테이블 스키마가 변경된 후 애플리케이션 코드가 업데이트되지 않은 경우, 새로 추가된 NOT NULL 컬럼에 대한 처리가 누락되어 에러가 발생하는 경우가 매우 많습니다.

2. DEFAULT 값 없이 NOT NULL 컬럼 추가

운영 중인 테이블에 기존 데이터가 존재하는 상태에서 DEFAULT 값 없이 NOT NULL 컬럼을 추가하려 할 때 발생합니다. 기존 행(row)들은 새로 추가되는 컬럼에 대한 값이 없기 때문에 PostgreSQL은 이를 NULL로 처리하려 하고, 이 시점에서 NOT NULL 제약과 충돌하여 에러가 발생합니다. 이는 무중단 배포(Zero Downtime Deployment) 환경에서 스키마 마이그레이션을 수행할 때 가장 빈번하게 발생하는 실수 중 하나입니다.

3. 외부 데이터 소스에서의 NULL 값 유입

CSV 파일, 외부 API, ETL 파이프라인 등 외부 데이터 소스로부터 데이터를 적재(load)할 때 데이터 품질이 보장되지 않아 NULL 값이 포함된 채로 삽입이 시도될 때 발생합니다. 특히 COPY 명령어나 INSERT INTO ... SELECT ... 구문을 사용하는 대량 데이터 처리 과정에서 소스 데이터의 특정 컬럼이 비어 있는 경우, 해당 컬럼이 대상 테이블에서 NOT NULL로 정의되어 있다면 전체 배치 작업이 실패할 수 있습니다.


해결 방법

원인 1: INSERT/UPDATE 시 값 누락 해결

에러 메시지를 통해 어떤 컬럼에서 위반이 발생했는지 확인한 후, 해당 컬럼에 적절한 값을 제공합니다.

-- 에러 발생 예시
INSERT INTO orders (customer_id, product_id, quantity)
VALUES (101, 55, NULL);
-- ERROR: null value in column "quantity" of relation "orders" 
-- violates not-null constraint

-- 해결: 적절한 값 제공
INSERT INTO orders (customer_id, product_id, quantity)
VALUES (101, 55, 1);

-- UPDATE 시 NULL 방지
UPDATE orders
SET quantity = COALESCE(quantity, 1)
WHERE quantity IS NULL;

컬럼에 기본값이 허용된다면, 테이블 정의에 DEFAULT를 추가하여 값 누락 시 자동으로 기본값이 채워지도록 합니다.

-- DEFAULT 값 추가로 근본 원인 해결
ALTER TABLE orders
ALTER COLUMN quantity SET DEFAULT 1;

원인 2: 기존 테이블에 NOT NULL 컬럼 안전하게 추가

기존 데이터가 있는 테이블에 NOT NULL 컬럼을 추가할 때는 단계적으로 접근해야 합니다.

-- 잘못된 방법 (기존 데이터가 있으면 에러 발생)
ALTER TABLE users ADD COLUMN last_login TIMESTAMP NOT NULL;
-- ERROR: column "last_login" of relation "users" contains null values

-- 올바른 방법 (3단계 접근)

-- 1단계: NULL 허용 상태로 컬럼 먼저 추가
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;

-- 2단계: 기존 행에 대한 값 채우기
UPDATE users SET last_login = NOW() WHERE last_login IS NULL;

-- 3단계: NOT NULL 제약 추가 (이제 안전하게 추가 가능)
ALTER TABLE users ALTER COLUMN last_login SET NOT NULL;

-- 확인
SELECT column_name, is_nullable, column_default
FROM information_schema.columns
WHERE table_name = 'users' AND column_name = 'last_login';

원인 3: 외부 데이터 적재 시 NULL 처리

COPY 또는 INSERT INTO ... SELECT 사용 시 COALESCE 또는 NULLIF 함수를 활용하여 NULL 값을 사전에 처리합니다.

-- 외부 데이터 적재 시 NULL 처리 예시 (INSERT INTO ... SELECT)
INSERT INTO target_table (user_id, email, status, created_at)
SELECT
    user_id,
    COALESCE(email, 'unknown@example.com'),  -- NULL이면 기본값 사용
    COALESCE(status, 'ACTIVE'),              -- NULL이면 'ACTIVE' 사용
    COALESCE(created_at, NOW())              -- NULL이면 현재 시각 사용
FROM staging_table
WHERE user_id IS NOT NULL;  -- user_id가 NULL인 행은 아예 제외

-- COPY 전 스테이징 테이블에서 검증
SELECT COUNT(*) AS null_count, column_name
FROM (
    SELECT 'email' AS column_name, COUNT(*) AS cnt
    FROM staging_table WHERE email IS NULL
    UNION ALL
    SELECT 'status', COUNT(*)
    FROM staging_table WHERE status IS NULL
) AS null_check
GROUP BY column_name;

예방 방법

1. 애플리케이션 레벨의 사전 유효성 검사 도입

데이터베이스에 도달하기 전에 애플리케이션 코드 단계에서 필수 필드 검증 로직을 반드시 구현하세요. ORM을 사용하는 경우 모델 정의 시 NOT NULL 컬럼에 대한 유효성 검사 규칙(예: required, non-null)을 명시적으로 선언하고, API 입력값에 대한 스키마 검증(JSON Schema, Pydantic 등)을 레이어별로 적용하면 데이터베이스 에러가 발생하기 전에 문제를 조기에 발견할 수 있습니다.

2. 스키마 변경 시 마이그레이션 스크립트 검토 프로세스 확립

운영 환경에 스키마 변경을 적용하기 전에 반드시 스테이징(Staging) 환경에서 실제 데이터와 유사한 볼륨으로 마이그레이션 스크립트를 테스트하는 프로세스를 확립하세요. 특히 NOT NULL 컬럼을 추가하거나 기존 컬럼의 NOT NULL 제약을 변경할 때는 반드시 롤백(Rollback) 계획을 함께 준비하고, 변경 전후 데이터 정합성을 검증하는 쿼리를 마이그레이션 스크립트에 포함시키는 것이 Best Practice입니다.


관련 에러

  • 23000 (integrity_constraint_violation): 23502의 상위 카테고리 에러로, 모든 무결성 제약 위반을 포괄합니다.
  • 23505 (unique_violation): UNIQUE 제약 조건 위반 에러로, 중복된 고유 키 값을 삽입하려 할 때 발생합니다. NOT NULL과 함께 Primary Key 관련 작업에서 자주 동반 발생합니다.
  • 23503 (foreign_key_violation): 외래 키 제약 조건 위반으로, 참조 대상 행이 존재하지 않을 때 발생합니다. 대량 데이터 마이그레이션 시 23502와 함께 발생하는 경우가 많습니다.
  • 42804 (datatype_mismatch): 컬럼의 데이터 타입과 삽입 값의 타입이 맞지 않을 때 발생하며, NULL 처리 과정에서 타입 캐스팅 실수와 함께 나타날 수 있습니다.

DBMS 에러 코드 시리즈

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

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

댓글 남기기