データベースマッピング
Prismaスキーマには、特定のデータベースオブジェクトの名前を定義できるメカニズムが含まれています。次のことができます。
コレクション/テーブル名とフィールド/カラム名のマッピング
データベース内のエンティティを記述するために使用される名前が、生成されたAPIで望ましい名前と一致しない場合があります。Prismaスキーマで名前をマッピングすることで、基になるデータベース名を変更することなく、Client APIでの命名に影響を与えることができます。
たとえば、データベースでテーブル/コレクションに名前を付ける一般的なアプローチは、複数形とsnake_case表記を使用することです。ただし、弊社では別の命名規則(単数形、PascalCase)を推奨しています。
@map
と@@map
を使用すると、基になるデータベースのテーブル名とカラム名からモデル名とフィールド名を分離することで、Prisma Client APIの構造を調整できます。
コレクション/テーブル名をマッピングする
例として、comments
という名前のテーブルを持つデータベースをイントロスペクトすると、結果のPrismaモデルは次のようになります。
model comments {
// Fields
}
ただし、@@map
属性を使用することで、基になるデータベースのcomments
テーブルの名前を変更することなく、モデルの名前としてComment
を選択(例:命名規則に従うため)できます。
model Comment {
// Fields
@@map("comments")
}
この変更されたモデル定義により、Prisma ClientはComment
モデルを基になるデータベースのcomments
テーブルに自動的にマッピングします。
フィールド/カラム名をマッピングする
カラム/フィールド名を@map
することもできます。
model Comment {
content String @map("comment_text")
email String @map("commenter_email")
type Enum @map("comment_type")
@@map("comments")
}
このようにして、comment_text
カラムはPrisma Client APIではprisma.comment.comment_text
として利用できませんが、prisma.comment.content
を介してアクセスできます。
enum名と値をマッピングする
enum値を@map
するか、enumを@@map
することもできます。
enum Type {
Blog,
Twitter @map("comment_twitter")
@@map("comment_source_enum")
}
制約名とインデックス名
属性@id
、@@id
、@unique
、@@unique
、@@index
、および@relation
について、map
引数を使用してPrismaスキーマで基になる制約名とインデックス名を明示的に定義できます。(これはPrisma ORMバージョン2.29.0以降で利用可能です。)
データベースをイントロスペクトする場合、map
引数は、名前がPrisma ORMのインデックスと制約のデフォルト命名規則と異なる場合にのみスキーマにレンダリングされます。
バージョン2.29.0より前のPrisma Migrateを使用しており、新しいバージョンにアップグレードした後も既存の制約名とインデックス名を維持したい場合は、すぐにprisma migrate
またはprisma db push
を実行**しないでください**。これにより、Prisma ORMの規則に従わない基になる制約名が変更されます。既存の制約名とインデックス名を維持できるアップグレードパスに従ってください。
名前付き制約のユースケース
明示的に名前を付けられた制約のユースケースには、次のようなものがあります。
- 会社の方針
- 他のツールの規則
インデックスと制約のPrisma ORMのデフォルト命名規則
Prisma ORMの命名規則は、決定論的であるためPostgreSQLに合わせるために選択されました。また、多くのデータベースがすでにこの規則に準拠しているため、名前をレンダリングする必要がない回数を最大化するのにも役立ちます。
Prisma ORMは、デフォルトのインデックス名と制約名を生成する際に、常にエンティティのデータベース名を使用します。モデルがデータモデル内で@@map
または@map
を介して別の名前に再マッピングされた場合でも、デフォルトの名前生成はデータベース内のテーブルの名前を入力として受け取ります。フィールドとカラムについても同様です。
エンティティ | 規則 | 例 |
---|---|---|
プライマリキー | {tablename}_pkey | User_pkey |
ユニーク制約 | {tablename}_{column_names}_key | User_firstName_last_Name_key |
非ユニークインデックス | {tablename}_{column_names}_idx | User_age_idx |
外部キー | {tablename}_{column_names}_fkey | User_childName_fkey |
ほとんどのデータベースにはエンティティ名の長さに制限があるため、データベースの制限に違反しないように、必要に応じて名前が切り詰められます。完全な名前が許容される最大長になるように、必要に応じて_suffix
の前の部分を短縮します。
デフォルトの制約名の使用
map
引数によって明示的な名前が提供されない場合、Prisma ORMはデフォルトの命名規則に従ってインデックス名と制約名を生成します。
データベースをイントロスペクトすると、インデックスと制約の名前は、Prisma ORMの命名規則に従っていない限り、スキーマに追加されます。もし従っている場合、スキーマをより読みやすくするために名前はレンダリングされません。そのようなスキーマをマイグレートすると、Prismaはデフォルトの名前を推測し、それらをデータベースに永続化します。
例
以下のスキーマは、3つの制約(@id
、@unique
、および@relation
)と1つのインデックス(@@index
)を定義しています。
model User {
id Int @id @default(autoincrement())
name String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name])
@@index([title, authorName])
}
map
引数によって明示的な名前が提供されていないため、Prismaはそれらがデフォルトの命名規則に従うと仮定します。
次の表は、基になるデータベースの各制約とインデックスの名前を一覧表示しています。
制約またはインデックス | 規則に従う | 基になる制約またはインデックスの名前 |
---|---|---|
@id (User > id フィールド上) | はい | User_pk |
@@index (Post 上) | はい | Post_title_authorName_idx |
@id (Post > id フィールド上) | はい | Post_pk |
@relation (Post > author 上) | はい | Post_authorName_fkey |
カスタム制約/インデックス名の使用
map
引数を使用して、基になるデータベースにカスタム制約およびインデックス名を定義できます。
例
以下の例では、1つの@id
と@@index
にカスタム名を追加します。
model User {
id Int @id(map: "Custom_Primary_Key_Constraint_Name") @default(autoincrement())
name String @unique
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name])
@@index([title, authorName], map: "My_Custom_Index_Name")
}
次の表は、基になるデータベースの各制約とインデックスの名前を一覧表示しています。
制約またはインデックス | 規則に従う | 基になる制約またはインデックスの名前 |
---|---|---|
@id (User > id フィールド上) | いいえ | Custom_Primary_Key_Constraint_Name |
@@index (Post 上) | いいえ | My_Custom_Index_Name |
@id (Post > id フィールド上) | はい | Post_pk |
@relation (Post > author 上) | はい | Post_authorName_fkey |
関連: Prisma Clientのインデックスとプライマリキーの命名
map
に加えて、@@id
と@@unique
属性はオプションのname
引数を受け入れ、Prisma Client APIをカスタマイズできます。
次のようなモデルの場合
model User {
firstName String
lastName String
@@id([firstName, lastName])
}
そのプライマリキーで選択するためのデフォルトAPIは、フィールドの生成された組み合わせを使用します。
const user = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: 'Paul',
lastName: 'Panther',
},
},
})
@@id([firstName, lastName], name: "fullName")
を指定すると、Prisma Client APIが代わりに次のように変更されます。
const user = await prisma.user.findUnique({
where: {
fullName: {
firstName: 'Paul',
lastName: 'Panther',
},
},
})