Prisma2を素振りしてみた
基本的には公式ドキュメントに書いてある
Prisma - Next-generation ORM for Node.js and TypeScript
そもそもPrismaとは何か
基本的なコンセプトはここに書いてある。
以下抜粋
Prisma is an open source next- generation ORM. It consists of the following parts:
- Prisma Client: Auto-generated and type-safe query builder for Node.js & TypeScript
- Prisma Migrate (experimental): Declarative data modeling & migration system
- Prisma Studio: GUI to view and edit data in your database
つまりPrismaはORM, マイグレーション機構、GUIクライアントを内包したツール。
インストールしたもの
Express + TypeScript + MySQL + Docker
で素振りした。
Prismaを使うのに必要だったのは以下の2点
- @prisma/client
- @prisma/cli
導入の仕方
基本的には公式ドキュメントのチュートリアルをやるのが一番理解が早い。
Add Prisma to an existing project (15 min)
自前のDockerで立てたMySQLに繋ぐ場合、prisma/.envには
HOST = 'http://127.0.0.1'
MYSQL_DATABASE = 'prisma_practice'
MYSQL_USER = 'root'
MYSQL_PASSWORD = 'password'
MYSQL_ROOT_PASSWORD = 'password'
としていた場合は
DATABASE_URL = "mysql://root:password@127.0.0.1:3306/prisma_practice?schema=public"
こんな感じになる。
使い方
基本的な流れとしては
- prisma/schema.prismaにprisma向けのデータモデルを記述して
prisma migrate save --experimental
prisma migrate up --experimental
を実行する。(schema.prismaはあくまでprismaにモデルを伝えるだけでこのファイルを変更しただけではDBには反映されない。なのでマイグレーションを行う。ただし--experimentalをつけている通りまだ安定版ではない)
- このままでは@prisma/clientで参照しているschema.prismaが最新版になっていないため補完が効かない。なので
$ npx prisma generate
を実行する。
自分は最後のコマンドを叩くのを知らず、スキーマを変更した後で補完が効かず焦った。
ドキュメントはしっかり読みましょう・・・。
リレーションの作成
ここに全て書いてある。(丸投げ感)
Explicit many-to-many relationsを作成した時
model User {
id Int @id @default(autoincrement())
name String?
email String @unique
age Int
posts Post[]
Profile Profile?
}
model Post {
id Int @id @default(autoincrement())
title String
createdAt DateTime @default(now())
content String?
published Boolean @default(false)
thumbnail String?
authorId Int
TagsOnPosts TagsOnPosts[]
author User @relation(fields: [authorId], references: [id])
@@index([authorId], name: "authorId")
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
User User @relation(fields: [userId], references: [id])
}
model Tag {
id Int @id @default(autoincrement())
name String
TagsOnPosts TagsOnPosts[]
}
model TagsOnPosts {
post Post @relation(fields: [postId], references: [id])
postId Int
tag Tag @relation(fields: [tagId], references: [id])
tagId Int
@@id([postId, tagId])
}
schema.prismaがこの時
const post = await this.prisma.post.findOne({
where: { id: Number(id) },
include: {
author: true,
TagsOnPosts: {
include: {
tag: true
}
}
}
})
多対多のリレーションを作成した時のデータの取得する時のコード。(中間テーブルを実装)
こんな感じでかけばpostに紐づいているタグも取得できる。
Explicit many-to-many relationsはいつ使うべきか?
ここに書いてある。
When you don't need to attach additional information to the relation, you can model m-n-relations as implicit many-to-many relations. If you're not using Prisma Migrate but obtain your data model from introspection, you can still make use of implicit many-to-many relations by following Prisma's conventions for relation tables.
つまり中間テーブルになんらかの追加情報(created_atとかがわかりやすい)を保存する場合はExplicit many-to-many relations
を使うと思われる。
最後に
すごい雑な記事でごめんなさい。
自分もまだ理解が追いついていないので間違った部分などございましたらコメントで指摘して頂けると助かります。
Discussion