189 lines
5.0 KiB
Markdown
189 lines
5.0 KiB
Markdown
# 마이그레이션 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. 추가된 데이터 정리 로직 (제약조건 추가 전)
|
|
|
|
```sql
|
|
-- 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: 전체 롤백 후 재실행 (권장)
|
|
|
|
```sql
|
|
-- 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: 데이터 정리만 수동 실행 후 재시도
|
|
|
|
```sql
|
|
-- 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. 나머지 제약조건들...
|
|
```
|
|
|
|
## 🧪 검증 쿼리
|
|
|
|
마이그레이션 실행 전에 문제 데이터 확인:
|
|
|
|
```sql
|
|
-- 문제가 되는 레코드 확인
|
|
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);
|
|
```
|
|
|
|
마이그레이션 실행 후 검증:
|
|
|
|
```sql
|
|
-- 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. **현재 상태 확인**
|
|
```bash
|
|
psql -h localhost -U postgres -d ilshin -f /Users/kimjuseok/ERP-node/db/check_numbering_rules.sql
|
|
```
|
|
|
|
2. **롤백 (필요시)**
|
|
- 기존 제약조건 제거
|
|
|
|
3. **수정된 마이그레이션 재실행**
|
|
```bash
|
|
PGPASSWORD=<비밀번호> psql -h localhost -U postgres -d ilshin -f /Users/kimjuseok/ERP-node/db/migrations/046_update_numbering_rules_scope_type.sql
|
|
```
|
|
|
|
4. **검증**
|
|
- 제약조건 확인
|
|
- 데이터 개수 확인
|
|
- 인덱스 확인
|
|
|
|
---
|
|
|
|
**수정 완료!** 이제 마이그레이션을 다시 실행하면 성공할 것입니다. 🎉
|
|
|