wing-ops/backend/src/db/seed.ts
htlee 199d5310db refactor(backend): SQLite → PostgreSQL 마이그레이션 + wing DB 연결
- better-sqlite3 제거, wingDb.ts (PostgreSQL wing DB Pool) 추가
- layers 라우터: 동기(better-sqlite3) → 비동기(pg) 전환
- LAYER 테이블 마이그레이션 SQL 생성 (database/migration/001_layer_table.sql)
- seed 스크립트 PostgreSQL 전환
- 문서 업데이트: CLAUDE.md, README.md, docs/README.md, COMMON-GUIDE.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 14:18:00 +09:00

107 lines
3.0 KiB
TypeScript
Executable File

import 'dotenv/config'
import fs from 'fs'
import path from 'path'
import { fileURLToPath } from 'url'
import { dirname } from 'path'
import { wingPool } from './wingDb.js'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
async function seedDatabase() {
console.log('wing DB 레이어 시드 시작...')
const client = await wingPool.connect()
try {
// CSV 파일 읽기
const csvPath = path.join(__dirname, '../../../_reference/LayerList.csv')
const csvContent = fs.readFileSync(csvPath, 'utf-8')
// CSV 파싱
const lines = csvContent.split('\n')
const rows: (string | number | null)[][] = []
for (let i = 1; i < lines.length; i++) {
const line = lines[i].trim()
if (!line) continue
const values: string[] = []
let current = ''
let inQuotes = false
for (let j = 0; j < line.length; j++) {
const char = line[j]
if (char === '"') {
inQuotes = !inQuotes
} else if (char === ',' && !inQuotes) {
values.push(current.trim())
current = ''
} else {
current += char
}
}
values.push(current.trim())
const row = values.map(v => {
if (v === 'NULL' || v === '') return null
return v.replace(/"/g, '')
})
if (row.length >= 6) {
rows.push([
row[0], // LAYER_CD
row[1], // UP_LAYER_CD
row[2], // LAYER_FULL_NM
row[3], // LAYER_NM
parseInt(row[4] || '0', 10), // LAYER_LEVEL
row[5], // WMS_LAYER_NM
])
}
}
console.log(`${rows.length}개의 레이어 데이터 삽입 중...`)
await client.query('BEGIN')
// 기존 데이터 삭제
await client.query('DELETE FROM LAYER')
// FK 제약 때문에 상위 레이어(낮은 레벨)부터 삽입
const sortedRows = rows.sort((a, b) => (a[4] as number) - (b[4] as number))
for (const row of sortedRows) {
await client.query(
`INSERT INTO LAYER (LAYER_CD, UP_LAYER_CD, LAYER_FULL_NM, LAYER_NM, LAYER_LEVEL, WMS_LAYER_NM)
VALUES ($1, $2, $3, $4, $5, $6)
ON CONFLICT (LAYER_CD) DO UPDATE SET
UP_LAYER_CD = EXCLUDED.UP_LAYER_CD,
LAYER_FULL_NM = EXCLUDED.LAYER_FULL_NM,
LAYER_NM = EXCLUDED.LAYER_NM,
LAYER_LEVEL = EXCLUDED.LAYER_LEVEL,
WMS_LAYER_NM = EXCLUDED.WMS_LAYER_NM`,
row
)
}
await client.query('COMMIT')
// 결과 확인
const { rows: countResult } = await client.query('SELECT COUNT(*) as count FROM LAYER')
console.log(`시드 완료! 총 ${countResult[0].count}개의 레이어가 저장되었습니다.`)
} catch (err) {
await client.query('ROLLBACK')
console.error('시드 실패:', err)
throw err
} finally {
client.release()
await wingPool.end()
}
}
seedDatabase().catch((err) => {
console.error(err)
process.exit(1)
})