🤖

Prismaでデータベースに作成されるテーブル名を指定する

2023/06/19に公開

結論

@@map("テーブル名")でテーブル名を指定する。

model User {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  email     String   @unique
  name      String?

  # テーブル名の指定
  @@map("users")
}

マイグレーションしたのにテーブルが参照できずにハマる

Prismaを触ってみていたのですが、マイグレーションでいきなり躓いてしまいました。

公式ドキュメントを参考にすると、Prismaでスキーマを定義する際には、モデルの名称を先頭大文字の単数形で指定するようです。

https://www.prisma.io/docs/concepts/components/prisma-schema#example

このようにスキーマを定義して、マイグレーションを行うと、データベースのテーブル名は、スキーマで定義した値と同じく、Userのように先頭大文字の単数形で作成されます。

# スキーマ定義

model User {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  email     String   @unique
  name      String?
}
# データベースに作成されたテーブル一覧

test_db=# \dt
               List of relations
 Schema |        Name        | Type  |  Owner   
--------+--------------------+-------+----------
 public | User               | table | postgres
 public | _prisma_migrations | table | postgres

テーブル定義を確認しようとしたところ、「テーブルが見つからない」のエラーが出ました。

test_db=# \d User;
Did not find any relation named "User".

Postgresqlでは、識別子をダブルクオーテーションで囲まない場合、小文字に変換されるそうです。
Userテーブルではなく、userテーブルを探して見つからないとなっているわけです。
https://qiita.com/yuba/items/3c4326e1f171a80543c8

# ダブルクオーテーションで囲むとテーブル定義が表示される

test_db=# \d "User"
                                          Table "public.User"
  Column   |              Type              | Collation | Nullable |              Default               
-----------+--------------------------------+-----------+----------+------------------------------------
 id        | integer                        |           | not null | nextval('"User_id_seq"'::regclass)
 createdAt | timestamp(3) without time zone |           | not null | CURRENT_TIMESTAMP
 email     | text                           |           | not null | 
 name      | text                           |           |          | 
Indexes:
    "User_pkey" PRIMARY KEY, btree (id)
    "User_email_key" UNIQUE, btree (email)

テーブル名を指定する方法

@@mapを利用すれば、テーブル名を自由につけることができます。

https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference#map-1

# スキーマ定義

model User {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  email     String   @unique
  name      String?

  @@map("users")
}
# データベースに作成されたテーブル一覧

test_db=# \dt
               List of relations
 Schema |        Name        | Type  |  Owner   
--------+--------------------+-------+----------
 public | _prisma_migrations | table | postgres
 public | users              | table | postgres
(2 rows)


SQLクライアントツールやORMを利用している際は、自動でダブルクオーテーションで囲ってくれているので、特に問題にならないかと思いますが、psqlで繋いでちょっと確認したり、コード内で生SQLを使ったりする場合には、ハマってしまうかもしれないですね。

デフォルトのまま利用するのか、各モデルでテーブル名を指定するのか、どっちがいいのかはわかってないですが、利用するなら自分でテーブル名つける気がする。

Discussion