웹 개발
데이터베이스 시드(seed) 데이터를 다룰 때 실수 줄이는 방법
데이터베이스 개발 환경을 셋업할 때 시드 스크립트가 제대로 작동하고 운영에 영향을 주지 않도록 관리하는 방법을 다룬다.
개발할 때 테스트 데이터가 필요하다. 보통 시드(seed) 스크립트로 초기 데이터를 넣는데, 이 과정에서 실수하면 로컬과 운영 환경의 데이터가 꼬인다.
시드 스크립트는 반드시 개발 환경에서만 작동하도록
시드 스크립트가 실수로 운영 환경에서 실행되는 상황을 방지해야 한다:
// prisma/seed.ts
const prisma = new PrismaClient();
// 반드시 환경 체크
if (process.env.NODE_ENV === 'production') {
console.error('❌ Seeding is not allowed in production!');
process.exit(1);
}
async function main() {
console.log('Seeding database...');
// 시드 데이터 생성
const user = await prisma.user.create({
data: {
email: '[email protected]',
name: 'Test User'
}
});
console.log(`Created user: ${user.id}`);
}
main()
.catch(e => console.error(e))
.finally(async () => await prisma.$disconnect());
시드 스크립트 실행 전에 확인사항
# 1. 현재 환경 변수 확인
echo $NODE_ENV
echo $DATABASE_URL
# 2. 데이터베이스 연결 확인
psql -U postgres -d mydb -c "SELECT version();"
# 3. 기존 데이터가 있는지 확인 (중복 피하기)
psql -U postgres -d mydb -c "SELECT COUNT(*) FROM users;"
멱등성(idempotency): 몇 번 실행해도 같은 결과
시드를 여러 번 실행해도 중복 데이터가 생기지 않도록:
async function seedUsers() {
const testUser = await prisma.user.upsert({
where: { email: '[email protected]' },
update: {}, // 이미 있으면 업데이트 안 함
create: {
email: '[email protected]',
name: 'Test User'
}
});
return testUser;
}
Or with explicit deletion:
async function seedUsers() {
// 기존 데이터 삭제
await prisma.user.deleteMany({
where: {
email: { startsWith: 'test-' }
}
});
// 새 데이터 생성
const user = await prisma.user.create({
data: {
email: '[email protected]',
name: 'Test User'
}
});
return user;
}
관계 있는 데이터(Foreign Key) 다루기
테이블 간 관계가 있으면 순서가 중요하다:
async function main() {
// 1. 부모 데이터 먼저
const user = await prisma.user.upsert({
where: { email: '[email protected]' },
update: {},
create: {
email: '[email protected]',
name: 'Test User'
}
});
// 2. 그 다음 자식 데이터
const post = await prisma.post.upsert({
where: { id: 'post-1' },
update: {},
create: {
id: 'post-1',
title: 'Test Post',
authorId: user.id
}
});
}
역순으로 하면 외래키 제약 위반 에러가 난다.
큰 데이터셋을 효율적으로 로드
수천 개의 테스트 데이터가 필요한 경우:
async function seedLargeDataset() {
const users = Array.from({ length: 1000 }, (_, i) => ({
email: `user${i}@example.com`,
name: `User ${i}`
}));
// 한 번에 여러 개 생성 (더 빠름)
await prisma.user.createMany({
data: users,
skipDuplicates: true
});
}
운영 환경으로의 실수 전환 방지
시드 데이터는 보통 특별한 마크를 해서 구분한다:
// 모든 시드 데이터에 특별한 플래그
const user = await prisma.user.create({
data: {
email: '[email protected]',
name: 'Test User',
isTestData: true // ← 이 플래그로 필터링 가능
}
});
이렇게 하면 운영 환경에서 실수로 테스트 데이터를 조회하지 않도록 쿼리를 짤 수 있다:
// 운영 환경에서는 테스트 데이터 제외
const users = await prisma.user.findMany({
where: {
isTestData: false
}
});
시드 스크립트 실행 기록
いつ、誰が、뭘 했는지 기록해두면 나중에 문제를 추적할 때 도움된다:
#!/bin/bash
# seed.sh
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Starting seed..." >> seed.log
echo "User: $(whoami)" >> seed.log
echo "Environment: $NODE_ENV" >> seed.log
node prisma/seed.ts >> seed.log 2>&1
if [ $? -eq 0 ]; then
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Seed completed successfully" >> seed.log
else
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Seed failed" >> seed.log
exit 1
fi
테스트 데이터 정리
테스트 후 정리하는 것도 중요하다:
# 모든 테스트 데이터 삭제
npx prisma db seed # 현재 정의된 시드로 재설정
# 또는 개발 DB 초기화
npx prisma migrate reset
시드 스크립트를 제대로 다루면 로컬 환경을 항상 깨끗하게 유지할 수 있고, 운영 데이터를 실수로 손상시키는 일을 방지할 수 있다.