メインコンテンツへスキップ

データベースマッピング

Prismaスキーマには、特定のデータベースオブジェクトの名前を定義できるメカニズムが含まれています。次のことができます。

コレクション/テーブル名とフィールド/カラム名のマッピング

データベース内のエンティティを記述するために使用される名前が、生成されたAPIで望ましい名前と一致しない場合があります。Prismaスキーマで名前をマッピングすると、基盤となるデータベース名を変更せずに、Client APIの名前付けに影響を与えることができます。

たとえば、データベース内のテーブル/コレクションの名前付けの一般的なアプローチは、複数形とsnake_case表記を使用することです。ただし、別の命名規則(単数形、PascalCase)をお勧めします。

@map@@mapを使用すると、基盤となるデータベースのテーブル名とカラム名からモデル名とフィールド名を切り離すことで、Prisma Client APIの形状を調整できます。

コレクション/テーブル名のマッピング

たとえば、commentsという名前のテーブルを持つデータベースをイントロスペクトすると、結果として得られるPrismaモデルは次のようになります。

model comments {
// Fields
}

ただし、基盤となるデータベースのcommentsテーブルの名前を変更せずに、モデルの名前としてCommentを選択(たとえば、命名規則に従うため)することもできます。@@map属性を使用します。

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 ORMバージョン2.29.0以降で利用可能です。)

データベースをイントロスペクトする場合、名前がPrisma ORMのインデックスと制約のデフォルトの命名規則と異なる場合のみmap引数がスキーマにレンダリングされます。

危険

2.29.0より前のバージョンのPrisma Migrateを使用しており、新しいバージョンにアップグレードした後も既存の制約名とインデックス名を維持したい場合は、すぐにprisma migrateまたはprisma db pushを実行**しないでください**。これは、**Prisma ORMの規則に従わない基盤となる制約名を変更します**。既存の制約名とインデックス名を維持できるアップグレードパスに従ってください。

名前付き制約のユースケース

明示的に名前が付けられた制約のユースケースには、次のようなものがあります。

  • 会社の方針
  • 他のツールの規則

Prisma ORMのインデックスと制約のデフォルトの命名規則

Prisma ORMの命名規則は、PostgreSQLと整合するように選択されました。これは決定論的であるためです。また、多くのデータベースがすでに規則に準拠しているため、名前をレンダリングする必要がない回数を最大化するのに役立ちます。

Prisma ORMは、デフォルトのインデックス名と制約名を生成するときに、常にエンティティのデータベース名を使用します。モデルが@@mapまたは@mapを介してデータモデル内の別の名前に再マッピングされた場合でも、デフォルトの名前生成はデータベース内の*テーブル*の名前を入力として使用します。フィールドと*カラム*についても同様です。

エンティティ規則
主キー{tablename}_pkeyUser_pkey
ユニーク制約{tablename}_{column_names}_keyUser_firstName_last_Name_key
非ユニークインデックス{tablename}_{column_names}_idxUser_age_idx
外部キー{tablename}_{column_names}_fkeyUser_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はそれらがデフォルトの命名規則に従っていると見なします。

次の表は、基盤となるデータベースの各制約とインデックスの名前を示しています。

制約またはインデックス規則に従う基盤となる制約名またはインデックス名
@idUser > idフィールド上)はいUser_pk
@@indexPost上)はいPost_title_authorName_idx
@idPost > idフィールド上)はいPost_pk
@relationPost > 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")
}

次の表は、基盤となるデータベースの各制約とインデックスの名前を示しています。

制約またはインデックス規則に従う基盤となる制約名またはインデックス名
@idUser > idフィールド上)いいえCustom_Primary_Key_Constraint_Name
@@indexPost上)いいえMy_Custom_Index_Name
@idPost > idフィールド上)はいPost_pk
@relationPost > author上)はいPost_authorName_fkey

mapに加えて、@@id属性と@@unique属性は、Prisma Client APIをカスタマイズできるオプションのname引数を受け入れます。

次のようなモデルの場合:

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',
},
},
})