본문으로 건너뛰기

Delete

모든 예시는 예시 스키마를 기반으로 합니다.

단일 레코드 삭제하기​

다음 질의는 delete를 사용하여 단일 User 레코드를 삭제합니다.

ts
const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})
ts
const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})

모든 Post에는 작성자가 필요하므로 하나 이상의 게시물이 있는 사용자를 삭제하려고 하면 오류가 발생합니다. 연속 삭제하기를 참고하세요.

여러 레코드 삭제하기​

다음 질의는 deleteMany를 사용하여 email에 prisma.io가 포함된 모든 User 레코드를 삭제합니다.

ts
const deleteUsers = await prisma.user.deleteMany({
where: {
email: {
contains: 'prisma.io',
},
},
})
ts
const deleteUsers = await prisma.user.deleteMany({
where: {
email: {
contains: 'prisma.io',
},
},
})

모든 Post에는 작성자가 필요하므로 하나 이상의 게시물이 있는 사용자를 삭제하려고 하면 오류가 발생합니다. 연속 삭제하기를 참고하세요.

모든 레코드 삭제하기​

다음 질의는 deleteMany를 사용하여 모든 User 레코드를 삭제합니다.

ts
const deleteUsers = await prisma.user.deleteMany({})
ts
const deleteUsers = await prisma.user.deleteMany({})

사용자에게 관련 레코드(예: 게시물)가 있으면 이 질의는 실패합니다. 이 경우 먼저 관련 레코드를 삭제해야 합니다.

연속 삭제하기 (관련 레코드 삭제하기)​

참고

2.26.0 이상에서는 참조 작업을 사용하여 연속 삭제를 수행할 수 있습니다.

다음 질의는 delete를 사용하여 단일 User 레코드를 삭제합니다.

ts
const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})
ts
const deleteUser = await prisma.user.delete({
where: {
email: 'bert@prisma.io',
},
})

그러나 예시 스키마에는 Post와 User 사이에 필수 관계가 있습니다. 즉, 게시물이 있는 사용자는 삭제할 수 없습니다.

The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.
The change you are trying to make would violate the required relation 'PostToUser' between the `Post` and `User` models.

이 오류를 해결하기 위해 다음을 수행할 수 있습니다.

  • 관계를 선택적으로 만듬

    prisma
    model Post {
    id Int @id @default(autoincrement())
    author User? @relation(fields: [authorId], references: [id])
    authorId Int?
    }
    prisma
    model Post {
    id Int @id @default(autoincrement())
    author User? @relation(fields: [authorId], references: [id])
    authorId Int?
    }
  • 사용자를 삭제하기 전에 게시물 작성자를 다른 사용자로 변경함

  • 트랜잭션에서 두 개의 개별 질의로 사용자와 모든 게시물을 삭제함 (모든 질의는 성공해야 함)

ts
const deletePosts = prisma.post.deleteMany({
where: {
authorId: 7,
},
})
const deleteUser = prisma.user.delete({
where: {
id: 7,
},
})
const transaction = await prisma.$transaction([deletePosts, deleteUser])
ts
const deletePosts = prisma.post.deleteMany({
where: {
authorId: 7,
},
})
const deleteUser = prisma.user.delete({
where: {
id: 7,
},
})
const transaction = await prisma.$transaction([deletePosts, deleteUser])

모든 테이블에서 모든 레코드 삭제하기​

때로는 모든 테이블에서 모든 데이터를 제거하지만 실제 테이블은 유지하고 싶을 때가 있습니다. 이것은 개발 환경과 테스트 중에 특히 유용할 수 있습니다.

다음은 프리즈마 클라이언트와 프리즈마 마이그레이트를 사용하여 모든 테이블에서 모든 레코드를 삭제하는 방법을 보여줍니다.

deleteMany로 모든 데이터 삭제하기​

테이블이 삭제되어야 하는 순서를 알면 deleteMany 함수를 사용할 수 있습니다. 이것은 $transaction에서 동기적으로 실행되며 모든 유형의 데이터베이스와 함께 사용할 수 있습니다.

ts
const deletePosts = prisma.post.deleteMany()
const deleteProfile = prisma.profile.deleteMany()
const deleteUsers = prisma.user.deleteMany()
// 이 트랜잭션은 동기적으로 실행되므로 deleteUsers가 마지막에 실행되야 합니다.
await prisma.$transaction([deleteProfile, deletePosts, deleteUsers])
ts
const deletePosts = prisma.post.deleteMany()
const deleteProfile = prisma.profile.deleteMany()
const deleteUsers = prisma.user.deleteMany()
// 이 트랜잭션은 동기적으로 실행되므로 deleteUsers가 마지막에 실행되야 합니다.
await prisma.$transaction([deleteProfile, deletePosts, deleteUsers])

✅ 장점

  • 스키마의 구조를 미리 알고 있을 때 잘 작동합니다.
  • 각 테이블 데이터를 동기적으로 삭제합니다.

❌ 단점

  • 관계형 데이터베이스로 작업할 때, deleteMany 함수는 관계형 제약 조건에 관계없이 테이블을 조회하고 TRUNCATE하는 보다 일반적인 솔루션에 비해 확장성이 떨어집니다. 이 확장성 문제는 몽고DB 커넥터를 사용할 때는 적용되지 않습니다.
참고

$transaction는 각 모델 테이블에 대해 연속 삭제를 수행하므로 순서대로 호출해야 합니다.

원시 SQL로 모든 데이터 삭제하기 / TRUNCATE​

원시 SQL를 사용하는 것이 익숙하다면 $executeRawUnsafe를 이용해 테이블에 TRUNCATE를 수행할 수 있습니다.

다음 예시에서 마이SQL 데이터베이스를 사용합니다. 이 경우에는 TRUNCATE를 실행하기 전에 제약 조건을 제거해야 합니다. 전체 프로세스는 $transaction으로 실행됩니다.

ts
const transactions: PrismaPromise<any>[] = []
transactions.push(prisma.$executeRaw`SET FOREIGN_KEY_CHECKS = 0;`)
const tablenames = await prisma.$queryRaw<
Array<{ TABLE_NAME: string }>
>`SELECT TABLE_NAME from information_schema.TABLES WHERE TABLE_SCHEMA = 'tests';`
for (const { TABLE_NAME } of tablenames) {
if (TABLE_NAME !== '_prisma_migrations') {
try {
transactions.push(prisma.$executeRawUnsafe(`TRUNCATE ${TABLE_NAME};`))
} catch (error) {
console.log({ error })
}
}
}
transactions.push(prisma.$executeRaw`SET FOREIGN_KEY_CHECKS = 1;`)
try {
await prisma.$transaction(transactions)
} catch (error) {
console.log({ error })
}
ts
const transactions: PrismaPromise<any>[] = []
transactions.push(prisma.$executeRaw`SET FOREIGN_KEY_CHECKS = 0;`)
const tablenames = await prisma.$queryRaw<
Array<{ TABLE_NAME: string }>
>`SELECT TABLE_NAME from information_schema.TABLES WHERE TABLE_SCHEMA = 'tests';`
for (const { TABLE_NAME } of tablenames) {
if (TABLE_NAME !== '_prisma_migrations') {
try {
transactions.push(prisma.$executeRawUnsafe(`TRUNCATE ${TABLE_NAME};`))
} catch (error) {
console.log({ error })
}
}
}
transactions.push(prisma.$executeRaw`SET FOREIGN_KEY_CHECKS = 1;`)
try {
await prisma.$transaction(transactions)
} catch (error) {
console.log({ error })
}

✅ 장점

  • 확장성
  • 매우 빠른 속도

❌ 단점

  • 작업을 취소할 수 없음
  • 예약된 SQL 키워드를 테이블 이름으로 사용하면 원시 질의를 실행하려고 할 때 문제가 발생할 수 있음

프리즈마 마이그레이트로 모든 기록 삭제하기​

프리즈마 마이그레이트를 사용한다면 migrate reset을 사용할 수 있습니다.

  1. 데이터베이스를 삭제함
  2. 새 데이터베이스를 만듬
  3. 마이그레이션을 적용함
  4. 데이터로 데이터베이스를 시드함