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

イントロスペクション

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が適切なケーシングを使用するように、一部のフィールドは二重引用符で囲んで記述されています。二重引用符を使用しない場合、PostgreSQLはすべてを小文字として読み取ります。

テーブルのグラフィカルな概要を展開

ユーザー

カラム名主キー外部キー必須デフォルト
idSERIAL✔️いいえ✔️自動インクリメント
nameVARCHAR(255)いいえいいえいいえ-
emailVARCHAR(255)いいえいいえ✔️-

投稿

カラム名主キー外部キー必須デフォルト
idSERIAL✔️いいえ✔️自動インクリメント
createdAtTIMESTAMPいいえいいえ✔️now()
titleVARCHAR(255)いいえいいえ✔️-
contentTEXTいいえいいえいいえ-
publishedBOOLEANいいえいいえ✔️false
authorIdINTEGERいいえ✔️✔️-

プロフィール

カラム名主キー外部キー必須デフォルト
idSERIAL✔️いいえ✔️自動インクリメント
bioTEXTいいえいいえいいえ-
userIdINTEGERいいえ✔️✔️-

次のステップとして、データベースをイントロスペクトします。イントロスペクションの結果は、Prismaスキーマ内のデータモデルになります。

データベースをイントロスペクトするには、次のコマンドを実行します

npx prisma db pull

このコマンドは、`.env`で定義されているDATABASE_URL環境変数を読み取り、データベースに接続します。接続が確立されると、データベースをイントロスペクトします(つまり、データベーススキーマを読み取ります)。次に、データベーススキーマをSQLからPrismaスキーマのデータモデルに変換します。

イントロスペクションが完了すると、Prismaスキーマが更新されます

Introspect your database with Prisma ORM

データモデルは次のようになります(モデルのフィールドは読みやすくするために並べ替えられていることに注意してください)

prisma/schema.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の命名規則に従っていません。より「セマンティクス」を表現するために、このフィールドの名前をauthorにして、UserPost間の関係をより良く記述することもできます。
  • UserPostおよびProfileリレーションフィールドと、ProfileUserリレーションフィールドはすべて大文字で始まっています。Prismaの命名規則に従うために、両方のフィールドを小文字のpostprofileuserにする必要があります。
  • 小文字にしても、Userpostフィールドの名前はまだ少し不適切です。それは、実際には投稿のリストを参照しているためです。したがって、より適切な名前は複数形のpostsになります。

これらの変更は、生成されたPrisma Client APIに関連しており、小文字のリレーションフィールドauthorpostsprofileuserを使用すると、JavaScript/TypeScript開発者にとってより自然で慣用的なものになります。したがって、Prisma Client APIを構成することができます。

リレーションフィールド仮想である(つまり、データベースに直接現れない)ため、データベースに触れることなくPrismaスキーマで手動で名前を変更できます

prisma/schema.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の設定ページをご覧ください。