-- ==================================================================== -- agenda_sections 테이블 마이그레이션 스크립트 -- -- 목적: -- 1. agenda_number: varchar(50) → integer 변환 -- 2. decisions, pending_items, todos: text → json 변환 -- 3. opinions 컬럼 삭제 (서비스에서 미사용) -- -- 실행 전 필수 작업: -- 1. 데이터베이스 백업 (pg_dump) -- 2. 테스트 환경에서 먼저 실행 및 검증 -- ==================================================================== -- 트랜잭션 시작 BEGIN; -- ==================================================================== -- 1단계: 백업 테이블 생성 (롤백용) -- ==================================================================== CREATE TABLE IF NOT EXISTS agenda_sections_backup AS SELECT * FROM agenda_sections; SELECT '✓ 백업 테이블 생성 완료: agenda_sections_backup' AS status; -- ==================================================================== -- 2단계: agenda_number 컬럼 타입 변경 (varchar → integer) -- ==================================================================== -- 데이터 검증: 숫자가 아닌 값이 있는지 확인 DO $$ DECLARE invalid_count INTEGER; BEGIN SELECT COUNT(*) INTO invalid_count FROM agenda_sections WHERE agenda_number !~ '^[0-9]+$'; IF invalid_count > 0 THEN RAISE EXCEPTION '숫자가 아닌 agenda_number 값이 % 건 발견됨. 데이터 정리 필요.', invalid_count; END IF; RAISE NOTICE '✓ agenda_number 데이터 검증 완료 (모두 숫자)'; END $$; -- 타입 변경 실행 ALTER TABLE agenda_sections ALTER COLUMN agenda_number TYPE integer USING agenda_number::integer; SELECT '✓ agenda_number 타입 변경 완료: varchar(50) → integer' AS status; -- ==================================================================== -- 3단계: JSON 컬럼 타입 변경 (text → json) -- ==================================================================== -- 3-1. decisions 컬럼 변경 ALTER TABLE agenda_sections ALTER COLUMN decisions TYPE json USING CASE WHEN decisions IS NULL OR decisions = '' THEN NULL ELSE decisions::json END; SELECT '✓ decisions 타입 변경 완료: text → json' AS status; -- 3-2. pending_items 컬럼 변경 ALTER TABLE agenda_sections ALTER COLUMN pending_items TYPE json USING CASE WHEN pending_items IS NULL OR pending_items = '' THEN NULL ELSE pending_items::json END; SELECT '✓ pending_items 타입 변경 완료: text → json' AS status; -- 3-3. todos 컬럼 변경 ALTER TABLE agenda_sections ALTER COLUMN todos TYPE json USING CASE WHEN todos IS NULL OR todos = '' THEN NULL ELSE todos::json END; SELECT '✓ todos 타입 변경 완료: text → json' AS status; -- ==================================================================== -- 4단계: opinions 컬럼 삭제 (서비스에서 미사용) -- ==================================================================== ALTER TABLE agenda_sections DROP COLUMN IF EXISTS opinions; SELECT '✓ opinions 컬럼 삭제 완료' AS status; -- ==================================================================== -- 5단계: 변경 사항 검증 -- ==================================================================== DO $$ DECLARE rec RECORD; BEGIN -- 테이블 구조 확인 SELECT column_name, data_type, character_maximum_length, is_nullable INTO rec FROM information_schema.columns WHERE table_name = 'agenda_sections' AND column_name = 'agenda_number'; RAISE NOTICE '========================================'; RAISE NOTICE '✓ 마이그레이션 검증 결과'; RAISE NOTICE '========================================'; RAISE NOTICE 'agenda_number 타입: %', rec.data_type; -- 데이터 건수 확인 RAISE NOTICE '원본 데이터 건수: %', (SELECT COUNT(*) FROM agenda_sections_backup); RAISE NOTICE '마이그레이션 후 건수: %', (SELECT COUNT(*) FROM agenda_sections); RAISE NOTICE '========================================'; END $$; -- ==================================================================== -- 커밋 또는 롤백 선택 -- ==================================================================== -- 문제가 없으면 COMMIT, 문제가 있으면 ROLLBACK 실행 -- 성공 시: COMMIT; -- 실패 시: ROLLBACK; COMMIT; SELECT ' ==================================================================== ✓ 마이그레이션 완료! 다음 작업: 1. 애플리케이션 재시작 2. 기능 테스트 수행 3. 문제 없으면 백업 테이블 삭제: DROP TABLE agenda_sections_backup; ==================================================================== ' AS next_steps;