イントロスペクション
Prisma ORMでデータベースをイントロスペクトする
このガイドでは、3つのテーブルを持つデモSQLスキーマを使用します。
CREATE TABLE "public"."User" (
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(255),
email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE "public"."Post" (
id SERIAL PRIMARY KEY NOT NULL,
title VARCHAR(255) NOT NULL,
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
content TEXT,
published BOOLEAN NOT NULL DEFAULT false,
"authorId" INTEGER NOT NULL,
FOREIGN KEY ("authorId") REFERENCES "public"."User"(id)
);
CREATE TABLE "public"."Profile" (
id SERIAL PRIMARY KEY NOT NULL,
bio TEXT,
"userId" INTEGER UNIQUE NOT NULL,
FOREIGN KEY ("userId") REFERENCES "public"."User"(id)
);
注記:一部のフィールドは、PostgreSQLが適切な casing(大文字小文字の区別)を使用するように、二重引用符で囲んで記述されています。二重引用符を使用しない場合、PostgreSQLはすべてを小文字として読み取ります。
テーブルのグラフィカルな概要を展開
User
カラム名 | 型 | 主キー | 外部キー | 必須 | デフォルト |
---|---|---|---|---|---|
id | SERIAL | ✔️ | いいえ | ✔️ | 自動インクリメント |
name | VARCHAR(255) | いいえ | いいえ | いいえ | - |
email | VARCHAR(255) | いいえ | いいえ | ✔️ | - |
Post
カラム名 | 型 | 主キー | 外部キー | 必須 | デフォルト |
---|---|---|---|---|---|
id | SERIAL | ✔️ | いいえ | ✔️ | 自動インクリメント |
createdAt | TIMESTAMP | いいえ | いいえ | ✔️ | now() |
title | VARCHAR(255) | いいえ | いいえ | ✔️ | - |
content | TEXT | いいえ | いいえ | いいえ | - |
published | BOOLEAN | いいえ | いいえ | ✔️ | false |
authorId | INTEGER | いいえ | ✔️ | ✔️ | - |
Profile
カラム名 | 型 | 主キー | 外部キー | 必須 | デフォルト |
---|---|---|---|---|---|
id | SERIAL | ✔️ | いいえ | ✔️ | 自動インクリメント |
bio | TEXT | いいえ | いいえ | いいえ | - |
userId | INTEGER | いいえ | ✔️ | ✔️ | - |
次のステップとして、データベースをイントロスペクトします。イントロスペクションの結果は、Prismaスキーマ内のデータモデルになります。
データベースをイントロスペクトするには、次のコマンドを実行します。
npx prisma db pull
このコマンドは、.env
で定義されているDATABASE_URL
環境変数を読み取り、データベースに接続します。接続が確立されると、データベースをイントロスペクトします(つまり、データベーススキーマを読み取ります)。次に、データベーススキーマをSQLからPrismaスキーマのデータモデルに変換します。
イントロスペクションが完了すると、Prismaスキーマが更新されます。
データモデルは、現在、このようになります(モデルのフィールドは、読みやすくするために並べ替えられていることに注意してください)。
model Post {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
content String?
published Boolean @default(false)
authorId Int
User User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model User {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
email String @unique @db.VarChar(255)
Post Post[]
Profile Profile?
}
Prisma ORMのデータモデルは、データベーススキーマの宣言的な表現であり、生成されたPrisma Clientライブラリの基盤として機能します。Prisma Clientインスタンスは、これらのモデルに合わせて調整されたクエリを公開します。
現在、データモデルにはいくつかの小さな「問題」があります。
User
リレーションフィールドは大文字で始まっているため、Prismaの命名規則に準拠していません。より多くの「セマンティクス」を表現するために、このフィールドがUser
とPost
間の関係をより良く記述するauthor
と呼ばれると良いでしょう。User
のPost
およびProfile
リレーションフィールドと、Profile
のUser
リレーションフィールドはすべて大文字で始まっています。Prismaの命名規則に準拠するために、両方のフィールドを小文字のpost
、profile
、およびuser
にする必要があります。- 小文字にしても、
User
のpost
フィールドの名前はまだ少し不適切です。それは、実際には投稿のリストを参照しているためです。したがって、より良い名前は複数形であるposts
でしょう。
これらの変更は、生成されたPrisma Client APIに関連しており、小文字のリレーションフィールドauthor
、posts
、profile
、およびuser
を使用すると、JavaScript/TypeScript開発者にとってより自然で慣用的に感じられます。したがって、Prisma Client APIを構成することができます。
リレーションフィールドは仮想的であるため(つまり、データベースに直接現れない)、データベースに触れることなくPrismaスキーマで手動で名前を変更できます。
model Post {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model User {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
email String @unique @db.VarChar(255)
posts Post[]
profile Profile?
}
この例では、データベーススキーマはPrisma ORMモデルの命名規則に従っていました(イントロスペクションから生成された仮想リレーションフィールドのみがそれらに準拠しておらず、調整が必要でした)。これにより、生成されたPrisma Client APIの人間工学が最適化されます。
カスタムモデル名とフィールド名の使用
ただし、Prisma Client APIで公開されるカラムとテーブルの名前に追加の変更を加えたい場合があります。一般的な例は、データベーススキーマでよく使用されるsnake_case表記を、JavaScript/TypeScript開発者にとってより自然に感じるPascalCaseおよびcamelCase表記に変換することです。
snake_case表記に基づいたイントロスペクションから次のモデルを取得したと仮定します。
model my_user {
user_id Int @id @default(autoincrement())
first_name String?
last_name String @unique
}
このモデルのPrisma Client APIを生成した場合、APIでsnake_case表記が採用されます。
const user = await prisma.my_user.create({
data: {
first_name: 'Alice',
last_name: 'Smith',
},
})
Prisma Client APIでデータベースのテーブル名とカラム名を使用したくない場合は、@map
および@@map
で構成できます。
model MyUser {
userId Int @id @default(autoincrement()) @map("user_id")
firstName String? @map("first_name")
lastName String @unique @map("last_name")
@@map("my_user")
}
このアプローチを使用すると、モデルとそのフィールドに好きな名前を付けることができ、@map
(フィールド名の場合)および@@map
(モデル名の場合)を使用して、基になるテーブルとカラムを指し示すことができます。Prisma Client APIは次のようになります。
const user = await prisma.myUser.create({
data: {
firstName: 'Alice',
lastName: 'Smith',
},
})
詳細については、Prisma Client APIの構成ページをご覧ください。