우당탕탕 우리네 개발생활

[Prisma] update와 updateMany의 where option은 다르다 본문

tech

[Prisma] update와 updateMany의 where option은 다르다

미스터카멜레온 2024. 3. 9. 17:46

최근 prisma 라이브러리에 대한 typing이 얼마나 섬세하게 작성되어 있는지 새삼 느낄 수 있었다.

 

const updateUser = await prisma.user.update({
  where: {
    email: 'viola@prisma.io',
  },
  /**
      Type '{ email: string; }' is not assignable to type 'UserWhereUniqueInput'.
      Object literal may only specify known properties, and 'email' does not exist in type 'UserWhereUniqueInput'.ts(2322)
        index.d.ts: The expected type comes from property 'where' which is declared here on type '{ select?: UserSelect | null | undefined; include?: UserInclude | null | undefined; data: (Without<UserUpdateInput, UserUncheckedUpdateInput> & UserUncheckedUpdateInput) | (Without<...> & UserUpdateInput); where: UserWhereUniqueInput; }'
  */
  data: {
    name: 'Viola the Magnificent',
  },
})

위 예시와 같이 'update' 함수를 사용할 일이 있었는데, where 조건에 원하는 필드를 넣으려고 했더니 typing 에러를 발생시키는 것이었다.

 

why??

 

// index.d.ts

export type UserWhereUniqueInput = {
    id?: number
    // email이 없다
}

export type UserWhereInput = {
    AND?: Enumerable<UserWhereInput>
    OR?: Enumerable<UserWhereInput>
    NOT?: Enumerable<UserWhereInput>
    id?: IntFilter | number
    email?: StringFilter | string // email이 여기에만 있다
    ...
}

...

에러를 확인해 보니, 위와 같이 update 함수의 where option에 적용되어있는 type은 SchemaWhereUniqueInput(위 예시에서는 UserWhereUniqueInput)이었고, 스키마를 정의할 때 아래와 같이 unique constraint가 걸려있는 필드만 사용이 가능했다. 반면에 updateMany 함수의 경우 다른 type인 SchemaWhereInput이 적용되어 있었고, 굳이 unique인덱싱이 되어있지 않은 필드들도 대입이 가능했다.(목적이 다건을 업데이트하는 함수이기 때문에 unique 한 필드만 사용할 필요가 굳이 없는 것이다.) 함수 네이밍에 알맞게 type정의를 나눠놓은 게 인상적이었다.

model User {
	...
    email String @unique // 방법 1
    
    @@unique(["email"], name: "User_email_unique_constraint") // 방법 2
}

보통 하나의 필드를 unique로 만드는 간단한 방법으로 '방법 1'을 이용하는데, 다중의 필드를 묶어서 unique constraint를 걸고 싶다면 '방법 2'를 사용하면 좋을 것 같다.

 

이 type checking덕분에 unique하게 사용해야 했던 필드에 unique constraint를 안 걸었다는 사실을 발견할 수 있었고, 이를 올바르게 수정할 수 있었다. 스키마를 정의할 때 더 정교하게 작성해야겠다는 다짐을 할 수 있었다. 또한 class, method 그리고 property 하나를 작성하더라도 구상한 의도에 맞는 정교한 typing을 작성할 수 있는 것이 프로다운 모습이라고 다시금 생각할 수 있었다.

 

참조

- https://www.prisma.io/docs/orm/prisma-client/queries/crud#update

 

CRUD (Reference)

How to perform CRUD with Prisma Client.

www.prisma.io