LoginSignup
3
0

More than 1 year has passed since last update.

Prisma4にアップグレードした際に$queryRawを使用している箇所でTypeError: Cannot mix BigInt and other types, use explicit conversionsが発生する問題

Last updated at Posted at 2023-01-24

はじめに

以前の記事でPrisma3系から4系にアップグレードする必要があるケースを書いたが、
その際に発生した問題について。

環境

  • Prisma(before): 3.13.0(<= 3.15.2)
  • Prisma(after): 4.8.0(>= 4.0.0)
  • Provider:MySQL

概要

あるテーブルのレコード件数を$queryRawで取得してレコード件数+1をログに出力する場合、一例ではあるが以下のように書くことができる。

const result = await this.prisma.$queryRaw<
  { count: number }[]
>`SELECT COUNT(*) AS count FROM users`
const count = result[0].count

console.log('count + 1 =', count + 1)

仮にusersテーブルに1,000件のレコード数が存在すれば以下のように何の問題もなく出力される。

count + 1 = 1001

しかし、Prisma3系(<= 3.15.2)から4系(>= 4.0.0)にアップグレードすると、
上記の実装はTypeErrorが発生してしまう。

TypeError: Cannot mix BigInt and other types, use explicit conversions

なぜにBigInt?となったがとりあえずcountの値と型を確認してみる。

console.log('count:', count)
console.log('typeof count:', typeof count)
count: 1000n
typeof count: bigint

確かにBigIntになっている。

ということでPrisma4のアップグレードガイドを確認してみると、
queryRawが返却するスカラー値の型に関する仕様変更が明記されていた。

$queryRawで取得したスカラー値をJSの対応する型にデシリアライズするように変更された模様。
スクリーンショット 2023-01-24 11.41.41.png
Int64の返却型がIntegerからBigIntになっている。

対応

queryRawのジェネリクスパラメータを{ count: bigint }[]に変更し、
代入時にNumberコンストラクタでNumber型(数値型)に変換する。

const result = await this.prisma.$queryRaw<
  { count: bigint }[]
>`SELECT COUNT(*) AS count FROM users`
const count = Number(result[0].count)

console.log('count:', count)
console.log('typeof count:', typeof count)
console.log('count + 1 =', count + 1)
count: 1000
typeof count: number
count + 1 = 1001

無事、Prisma3系を使用していた際に期待していた出力結果と同じ出力結果を確認できた。

ただし、当然のことながら$queryRawで取得したBigInt型(長整数型)のレコード件数が、
Number型(数値型)で扱える範囲を超えてしまっている場合には精度が落ちるので注意を。

まとめ

Prisma3系(<= 3.15.2)から4系(>= 4.0.0)にアップグレードする際、
$queryRawを使用している箇所には注意しましょう。

本記事では単純な加算処理を例に挙げたが、
実際にこの問題に直面したケースではGraphQLのEntityにマッピングする箇所で発生したので、
アプリケーションのアーキテクチャ全体に関わる問題かと思いひやっとした。

参考

関連

Prismaで新規レコード作成時に@default(now())なカラムと@updatedAtなカラムに差異が生じる問題

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0