PrismaでDBのhasOneを試す
前の記事
今回
外部キーの定義って
後付けや変更ができないのかな?
普段SQLを使うことが多かったので今回prisma migrate dev
でエラーでできないから分かっていない・・・
設定したもの
prisma/schema.prisma
// This is your Prisma schema file, // learn more about it in the docs: https://pris.ly/d/prisma-schema generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } // ER図作成用 generator erd { provider = "prisma-erd-generator" output = "../doc/ERD.md" } // ユーザーデータ管理用 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? // 記事(One to Many) posts Post[] // テーブルの物理名 @@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") } // 記事管理用 model Post { // ID id Int @id @default(autoincrement()) // タイトル title String @map("title") // 登録日時 createdAt DateTime @default(now()) @map("created_at") // 更新日時 updatedAt DateTime @default(now()) @map("updated_at") // 親テーブルの関連づけ userId Int user User @relation(fields: [userId], references: [id]) // テーブルの物理名 @@map("posts") }
migrate後の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=19 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; CREATE TABLE `posts` ( `id` int NOT NULL AUTO_INCREMENT, `title` varchar(191) COLLATE utf8mb4_unicode_ci NOT NULL, `created_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), `updated_at` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3), `userId` int NOT NULL, PRIMARY KEY (`id`), KEY `posts_userId_fkey` (`userId`), CONSTRAINT `posts_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE RESTRICT ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
データ取得方法
基本は前回と同じ、今回は1対多のため、関連テーブルの条件絞り込みが可能
const user3 = await prisma.user.findFirst({ where: { name: 'hoge1' }, include: { profile: { select: { nickName: true, createdAt: true, }, }, posts: { select: { title: true }, where: { title: "test1" } } }, }) console.log("case3: ", user3)
↓
配下を全件取得した場合
id: 16, email: 'hoge1@example.com', name: 'hoge1', age: 20, createdAt: 2021-11-23T09:58:03.729Z, updatedAt: 2021-11-23T09:58:03.729Z, profile: { id: 5, nickName: 'aaaa', createdAt: 2021-11-23T09:58:03.729Z, updatedAt: 2021-11-23T09:58:03.729Z, userId: 16 }, posts: [ { id: 1, title: 'test1', createdAt: 2021-11-23T09:58:03.729Z, updatedAt: 2021-11-23T09:58:03.729Z, userId: 16 }, { id: 2, title: 'test2', createdAt: 2021-11-23T09:58:03.729Z, updatedAt: 2021-11-23T09:58:03.729Z, userId: 16 }, { id: 3, title: 'test3', createdAt: 2021-11-23T09:58:03.729Z, updatedAt: 2021-11-23T09:58:03.729Z, userId: 16 } ] }
一部のみ取得した場合
case3: { id: 16, email: 'hoge1@example.com', name: 'hoge1', age: 20, createdAt: 2021-11-23T09:58:03.729Z, updatedAt: 2021-11-23T09:58:03.729Z, profile: { nickName: 'aaaa', createdAt: 2021-11-23T09:58:03.729Z }, posts: [ { title: 'test1' } ] }
所感
ある程度のことはやってくれるイメージ
外部キーのこともあるから頻繁にデータ構造が変わる場合や複雑なSQLがある場合は不向き
次は多対多かgroup by
辺りを見てみる