💽

PrismaとPostgreSQLを組み合わせたときにハマる可能性のある問題

に公開

みなさんこんにちは!
今回は、PrismaでPostgreSQL上にテーブルを作成した後に、SQLクライアントでデータを参照しようとした際に私がややハマった問題について共有します。

Prismaでのテーブル作成

Prismaは、データベース操作を簡単にするためのORM(Object-Relational Mapping)ツールです。Prismaでは、モデル名やフィールド名をキャメルケースで記述するのが一般的です。
例えば、以下のようなPrismaのモデル定義があります。

model UserAccounts {
  userID   Int    @id @default(autoincrement())
  userName String
}

この定義に基づいて、Prismaのmigrateコマンドを実行すると、内部ではおそらく以下のようなSQLが発行されてテーブルが作成されます。(注:実際のロジックは未確認です)

CREATE TABLE "UserAccounts" (
    "userID" SERIAL PRIMARY KEY,
    "userName" VARCHAR(50)
);

ここで注意したいのが、モデル定義のままテーブル名やカラム名が大文字を含む形になっていることです。

SQLを直接書く際に発生し得る問題

Prismaが生成するクライアントを利用してビジネスロジックを記載している場合などには問題は起きませんが、たとえばSQLクライアントからテーブルの内容を参照しようとしたり、バッチを書こうとしたりする際に問題が起きる可能性があります。
例えば、以下のクエリを実行するとします。

SELECT userID, userName FROM UserAccounts;

このクエリはエラーになります。
なぜなら、PostgreSQLはクエリ上で大文字で記載されたテーブル名やカラム名を自動的に小文字に変換して解釈するため、存在しないテーブルやカラムとして扱われるからです。

正しいクエリはこんな感じです。

SELECT "userID", "userName" FROM "UserAccounts";

ダブルクオートで囲むことで、正しく大文字を含むテーブル名やカラム名を指定することができます。

解決策

そもそもテーブル名やカラム名を小文字のみを用いた形にすることが無難です。

Prismaスキーマの設定:Prismaのモデル定義上 @map@@map を用いることで、モデル名とは別にDB上で設定されるテーブル名やカラム名を設定することができます。
これを利用して、DB定義としては一般的なで小文字のスネークケース(snake_case)を設定することができます。
以下はその一例です。

```prisma
model UserAccounts {
  userId   Int    @id @default(autoincrement()) @map("user_id")
  userName String @map("user_name")
}

@@map("user_accounts")
```

以下の公式ドキュメントも参照してください。

https://www.prisma.io/docs/orm/reference/prisma-schema-reference#map-1
https://www.prisma.io/docs/orm/prisma-client/setup-and-configuration/custom-model-and-field-names

まとめ

Prismaを使ってPostgreSQLで大文字を含むテーブル名やカラム名を作成する場合、自分でSQLを書く際にはダブルクオートで囲む必要があることに注意しましょう。

PrismaとPostgreSQLの組み合わせをうまく活用して、スムーズなデータベース運用を目指しましょう! Happy coding!

SMARTCAMP Engineer Blog

Discussion