😀

【Prisma入門】スキーマ定義で使用するデコレーターあれこれ

2023/07/16に公開

はじめに

最近、Prismaを使用する機会が多いので、よく使うデコレーターについてまとめようと思います。
デコレーターというのは「@」で始まるもので、@idなどのことを言います。

Prismaの主要なデコレーター

Prismaのデコレーターはフィールドレベルのものとモデルレベルのものに分かれます。
違いは @の数です。

フィールドレベルでは「@」は1つつけますが、モデルレベルでは「@」を2つつけます。

::: note info
フィールドレベルの主要デコレーター
:::

デコレーター 解説 備考
@id フィールドを主キーとする -
@unique フィールドにユニーク制約を適用する -
@default フィールドのデフォルト値を設定する 例えば、@default(autoincrement())でIDフィールドが自動的にインクリメントされるように設定できる
@updatedAt フィールドの更新日時を自動的に設定する -
@createdAt フィールドの作成日時を自動的に設定する -
@map DBでのフィールド名とPrismaのモデル名が異なる場合にマッピングする 例えば、DBのフィールド名が「user_id」、Prismaのモデル名が「userId」の場合、@map("user_id")とするとマッピングできる
@relation 2つのモデル間でリレーションを設定できる 例えば、Userモデルとリレーションを組む場合、@relation(fields: [userId], references: [id], onDelete: Cascade) と、fieldsに参照されるモデルのフィールド(基本的にはID、この例の場合、PostモデルのuserId)を、referencesに参照先のモデルのフィールド(基本的にはID、この例の場合、Userモデルのid)を設定する。また、オプションとして、onDelete:Cascadeとすることで、親テーブルの関連データが削除されると、子テーブルの関連するデータも削除することができる
@db DBの特定の方にマップするために使用する -

::: note info
モデルレベルの主要デコレーター
:::

デコレーター 解説 備考
@@id 複数のフィールドを主キーに設定する -
@@unique 複数のフィールドに対してユニーク制約を設定 -
@@index 複数のフィールドにインデックスを作成する -
@@map DBのテーブル名とPrismaモデル名がことなる場合に使用する 例えば、PrismaモデルUserでテーブル名がusersの場合、@@map("users")とすることでマッピングできる
@@ignore Prisma Clientから特定のモデルを除外する -

使用例

@id

単一フィールドをIDとして定義。
cuidやuuidをしていすることもできる。

  • cuid()
  • uuid()
model User {
  id  Int  @id @default(autoincrement())
 }

@unique

model User {
  email String @unique
  name  String
}
model User {
  id      Int      @id @default(autoincrement())
  role    Role     @default(USER)
}

@default

model User {
  email  String @unique
  number Float  @default(1.1)
}
model User {
  email  String @unique
  number Decimal @default(22.99)
  createdAt DateTime @default(now())
}
enum Role {
  USER
  ADMIN
}

@createdAt・@updatedAt

model Post {
  id        String   @id
  createdAt DateTime @createdAt
  updatedAt DateTime @updatedAt
}

@map

実際のDBのフィールド名がnameの場合は以下のように定義する。

model Usre {
  userId        String   @id @default(autoincrement()) @map("user_id")
  username @map("name")
}

@relation

model Profile {
  authorId Int    @id
  author   User   @relation(fields: [authorId], references: [id])
  bio      String
}

model User {
  id      Int      @id
  email   String   @unique
  name    String?
  profile Profile?
}

@db

model User {
  id        Int     @id 
  username  String  @db.VarChar(300)
}

@@id

複合主キーを定義できる。

model User {
  firstName String
  lastName  String
  email     String  @unique
  isAdmin   Boolean @default(false)

  @@id([firstName, lastName])
}

@@unique

複合ユニーク属性を定義できる。

model User {
  id        Int     @default(autoincrement())
  firstName String
  lastName  String
  isAdmin   Boolean @default(false)

  @@unique([firstName, lastName])
}

@@index

インデックスを指定。

model Post {
  id      Int     @id @default(autoincrement())
  title   String
  content String?

  @@index([title])
}
model Post {
  id      Int     @id @default(autoincrement())
  title   String
  content String?

  @@index([title, content])
}

@@map

実際のDBのテーブル名がusresの場合は以下のように定義する。

model User {
  id           Int     @id @default(autoincrement())
  name         String?
  writtenPosts Post[]
  pinnedPost   Post?

  @@map('users')
}

@@ignore

SystemLogモデルをPrisma Clientから無視する。
@@ignoreをつけると、そのモデルでPrisma ClientによるCRUD操作ができなくなる。

要するにprisma.create()などのメソッドがそのモデルに対して使用できなくなる。
(Prismaで直接操作しなくないモデル(内部的なログやシステムデータなど)に適用する)

@@ignore
model SystemLog {
  id        Int      @id @default(autoincrement())
  message   String
  createdAt DateTime @default(now())
}

参考文献

Discussion