ERP-node/db/migrations/046_MIGRATION_FIX.md

5.0 KiB

마이그레이션 046 오류 수정

🚨 발생한 오류

SQL Error [23514]: ERROR: check constraint "check_menu_scope_requires_menu_objid" 
of relation "numbering_rules" is violated by some row

🔍 원인 분석

기존 데이터베이스에 scope_type='menu'인데 menu_objid가 NULL인 레코드가 존재했습니다.

제약조건을 추가하기 전에 이러한 불완전한 데이터를 먼저 정리해야 했습니다.

수정 내용

마이그레이션 파일 046_update_numbering_rules_scope_type.sql데이터 정리 단계 추가:

1. 추가된 데이터 정리 로직 (제약조건 추가 전)

-- 3. 기존 데이터 정리 (제약조건 추가 전 필수!)

-- 3.1. menu 타입인데 menu_objid가 NULL인 경우 → global로 변경
UPDATE numbering_rules
SET scope_type = 'global',
    table_name = NULL
WHERE scope_type = 'menu' AND menu_objid IS NULL;

-- 3.2. global 타입인데 table_name이 있는 경우 → table로 변경
UPDATE numbering_rules
SET scope_type = 'table'
WHERE scope_type = 'global' AND table_name IS NOT NULL;

-- 3.3. 정리 결과 확인 (로그)
DO $$
DECLARE
  menu_count INTEGER;
  global_count INTEGER;
  table_count INTEGER;
BEGIN
  SELECT COUNT(*) INTO menu_count FROM numbering_rules WHERE scope_type = 'menu';
  SELECT COUNT(*) INTO global_count FROM numbering_rules WHERE scope_type = 'global';
  SELECT COUNT(*) INTO table_count FROM numbering_rules WHERE scope_type = 'table';
  
  RAISE NOTICE '=== 데이터 정리 완료 ===';
  RAISE NOTICE 'Menu 규칙: % 개', menu_count;
  RAISE NOTICE 'Global 규칙: % 개', global_count;
  RAISE NOTICE 'Table 규칙: % 개', table_count;
  RAISE NOTICE '=========================';
END $$;

2. 실행 순서 변경

변경 전:

  1. scope_type 제약조건 추가
  2. 유효성 제약조건 추가 (여기서 오류 발생!)
  3. 데이터 마이그레이션

변경 후:

  1. scope_type 제약조건 추가
  2. 기존 데이터 정리 (추가)
  3. 유효성 제약조건 추가
  4. 인덱스 생성
  5. 통계 업데이트

🔄 재실행 방법

옵션 1: 전체 롤백 후 재실행 (권장)

-- 1. 기존 마이그레이션 롤백
BEGIN;

-- 제약조건 제거
ALTER TABLE numbering_rules DROP CONSTRAINT IF EXISTS check_scope_type;
ALTER TABLE numbering_rules DROP CONSTRAINT IF EXISTS check_table_scope_requires_table_name;
ALTER TABLE numbering_rules DROP CONSTRAINT IF EXISTS check_global_scope_no_table_name;
ALTER TABLE numbering_rules DROP CONSTRAINT IF EXISTS check_menu_scope_requires_menu_objid;

-- 인덱스 제거
DROP INDEX IF EXISTS idx_numbering_rules_scope_table;
DROP INDEX IF EXISTS idx_numbering_rules_scope_menu;

COMMIT;

-- 2. 수정된 마이그레이션 재실행
\i /Users/kimjuseok/ERP-node/db/migrations/046_update_numbering_rules_scope_type.sql

옵션 2: 데이터 정리만 수동 실행 후 재시도

-- 1. 데이터 정리
UPDATE numbering_rules
SET scope_type = 'global',
    table_name = NULL
WHERE scope_type = 'menu' AND menu_objid IS NULL;

UPDATE numbering_rules
SET scope_type = 'table'
WHERE scope_type = 'global' AND table_name IS NOT NULL;

-- 2. 제약조건 추가
ALTER TABLE numbering_rules
ADD CONSTRAINT check_menu_scope_requires_menu_objid
CHECK (
  (scope_type = 'menu' AND menu_objid IS NOT NULL)
  OR scope_type != 'menu'
);

-- 3. 나머지 제약조건들...

🧪 검증 쿼리

마이그레이션 실행 전에 문제 데이터 확인:

-- 문제가 되는 레코드 확인
SELECT 
  rule_id,
  rule_name,
  scope_type,
  table_name,
  menu_objid,
  company_code
FROM numbering_rules
WHERE 
  (scope_type = 'menu' AND menu_objid IS NULL)
  OR (scope_type = 'global' AND table_name IS NOT NULL)
  OR (scope_type = 'table' AND table_name IS NULL);

마이그레이션 실행 후 검증:

-- 1. scope_type별 개수
SELECT scope_type, COUNT(*) as count
FROM numbering_rules
GROUP BY scope_type;

-- 2. 제약조건 확인
SELECT conname, pg_get_constraintdef(oid)
FROM pg_constraint
WHERE conrelid = 'numbering_rules'::regclass
  AND conname LIKE '%scope%';

-- 3. 인덱스 확인
SELECT indexname, indexdef
FROM pg_indexes
WHERE tablename = 'numbering_rules'
  AND indexname LIKE '%scope%';

📝 수정 내역

  • 제약조건 추가 전 데이터 정리 로직 추가
  • 중복된 데이터 마이그레이션 코드 제거
  • 섹션 번호 재정렬
  • 데이터 정리 결과 로그 추가

🎯 다음 단계

  1. 현재 상태 확인

    psql -h localhost -U postgres -d ilshin -f /Users/kimjuseok/ERP-node/db/check_numbering_rules.sql
    
  2. 롤백 (필요시)

    • 기존 제약조건 제거
  3. 수정된 마이그레이션 재실행

    PGPASSWORD=<비밀번호> psql -h localhost -U postgres -d ilshin -f /Users/kimjuseok/ERP-node/db/migrations/046_update_numbering_rules_scope_type.sql
    
  4. 검증

    • 제약조건 확인
    • 데이터 개수 확인
    • 인덱스 확인

수정 완료! 이제 마이그레이션을 다시 실행하면 성공할 것입니다. 🎉