PrismaでDBのhasOneを試す
Prisma
hasOneについて
2つのテーブルが1対1、または0の関係のリレーショナル構造のこと
イメージ
Prismaでの定義の方法
prisma/schema.prisma
// ユーザーデータ管理用 model User { // ID id Int @id @default(autoincrement()) // メールアドレス email String @unique // 氏名 name String? // 年齢 age Int? // 登録日時 createdAt DateTime @default(now()) @map("created_at") // 更新日時 updatedAt DateTime @default(now()) @map("updated_at") // プロフィール(One to One) profile Profile? // テーブルの物理名 @@map("users") } // プロフィール管理用 model Profile { // ID id Int @id @default(autoincrement()) // ニックネーム nickName String @map("nick_name") // 登録日時 createdAt DateTime @default(now()) @map("created_at") // 更新日時 updatedAt DateTime @default(now()) @map("updated_at") // 親テーブルの関連づけ userId Int @unique user User @relation(fields: [userId], references: [id]) // テーブルの物理名 @@map("profile") }
親モデルへの追加定義
// プロフィール(One to One)
profile Profile?
これを追加することで関連するモデルが1または0の状態となる
子モデルへの追加定義
// 親テーブルの関連づけ userId Int @unique user User @relation(fields: [userId], references: [id])
紐付け用のカラムを追加し親と関連づける
マイグレーション後のCREATE文
CREATE TABLE `users` ( `id` int NOT NULL AUTO_INCREMENT, `email` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `name` varchar(191) COLLATE utf8mb4_unicode_ci DEFAULT NULL, `age` int DEFAULT NULL, `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), PRIMARY KEY (`id`), UNIQUE KEY `users_email_key` (`email`) ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE `profile` ( `id` int NOT NULL AUTO_INCREMENT, `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), `userId` int NOT NULL, `nick_name` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `profile_userId_key` (`userId`), CONSTRAINT `profile_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
データ処理
親のみ取得
const user1 = await prisma.user.findFirst({ where: { name: 'hoge1' }, }) console.log("case1: ", user1)
親子のデータを同時に取得
const user2 = await prisma.user.findFirst({ where: { name: 'hoge1' }, include: { profile: true, }, }) console.log("case2: ", user2)
子のデータを一部のみ取得
const user3 = await prisma.user.findFirst({ where: { name: 'hoge1' }, include: { profile: { select: { nickName: true, createdAt: true, }, }, }, }) console.log("case3: ", user3)
子のデータより親を引き出す
const profile1 = prisma.profile.findFirst({ where: { nickName: 'aaaa' }, }); const user4 = await profile1.user(); profile1.then((result) => { console.log("case4: ", result, user4); })
↓
case1: { id: 10, email: 'hoge1@example.com', name: 'hoge1', age: 20, createdAt: 2021-11-23T01:14:46.450Z, updatedAt: 2021-11-23T01:14:46.450Z } case2: { id: 10, email: 'hoge1@example.com', name: 'hoge1', age: 20, createdAt: 2021-11-23T01:14:46.450Z, updatedAt: 2021-11-23T01:14:46.450Z, profile: { id: 3, nickName: 'aaaa', createdAt: 2021-11-23T01:14:46.450Z, updatedAt: 2021-11-23T01:14:46.450Z, userId: 10 } } case3: { id: 10, email: 'hoge1@example.com', name: 'hoge1', age: 20, createdAt: 2021-11-23T01:14:46.450Z, updatedAt: 2021-11-23T01:14:46.450Z, profile: { nickName: 'aaaa', createdAt: 2021-11-23T01:14:46.450Z } } case4: { id: 3, nickName: 'aaaa', createdAt: 2021-11-23T01:14:46.450Z, updatedAt: 2021-11-23T01:14:46.450Z, userId: 10 } { id: 10, email: 'hoge1@example.com', name: 'hoge1', age: 20, createdAt: 2021-11-23T01:14:46.450Z, updatedAt: 2021-11-23T01:14:46.450Z }
親だけ削除とかはできんかった
多分、リレーションの設定で削除も連動するようにしてないせいと思うが seedファイルを改修する際に、削除⇨作成したらエラーになる。 ちょっと気をつけよう