NoSQL教団の人間が、Prismaに出会った
はじめに:SQLと僕の微妙な関係
正直に言います。僕、SQL苦手でした。
いや、SELECT文くらいなら書けるんですよ。SELECT * FROM users WHERE id = 1みたいなやつ。でもね、複数テーブルのJOINとか出てくるともうダメ。「これINNER JOINだっけ?LEFT JOINだっけ?」って毎回ググってました。
サブクエリとか出てきた日には、もう頭がパニック。「あれ、この括弧どこで閉じるんだっけ」「カンマの位置ここで合ってる?」みたいな。
もっと楽にDB触りたいよね...って思ってたんです。
Prismaとの出会い
そんなある日、Next.jsのチュートリアルを見てたら「Prisma」って文字が目に入りました。
「TypeScriptで型安全にDB操作できるORM」
...型安全?TypeScript?それは興味ある。
僕のポリシー「迷ったらとりあえず試してみる」の精神で触ってみたら、これがもう革命的でヤバすぎたんですよね。
Prismaって何者?
簡単に説明すると、PrismaはNode.js/TypeScript用のORMです。ORMってのは「Object-Relational Mapping」の略で、要はオブジェクト指向でデータベースを扱えるようにしてくれるやつ。
Prismaの特徴はこんな感じ:
- Prisma Schemaでモデルを定義する
- Prisma Clientで型安全にクエリを実行できる
- TypeScriptの型推論がバッチリ効く
- マイグレーション機能も付いてる
生SQLを書かなくても、JavaScriptのメソッドチェーンみたいな感覚でDB操作できるんです。これは楽。
セットアップが意外と簡単だった
まずはインストールから。
npm install prisma --save-dev
npm install @prisma/client
次にPrismaの初期化:
npx prisma init
これでprisma/schema.prismaファイルと.envファイルが生成されます。
.envにデータベースの接続情報を書きます:
DATABASE_URL="postgresql://user:password@localhost:5432/mydb"
PostgreSQL、MySQL、SQLite、SQL Server、MongoDBに対応してるので、好きなの使えます。僕は開発環境ではSQLite使うことが多いかな。楽だし。あと地味にMongoに対応してるのが嬉しいです。元々”NoSQL教団”の人間だったので
Prisma Schemaを書いてみる
schema.prismaファイルにモデルを定義していきます。こんな感じ:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
createdAt DateTime @default(now())
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
createdAt DateTime @default(now())
}
リレーションもこんな風に直感的に書けます。UserとPostが1対多の関係になってるのが見た目でわかりやすい。昔GraphQLのスキーマを見て感動したんですが、それを地でやってる感じ?
スキーマを書いたら、マイグレーションを実行:
npx prisma migrate dev --name init
これでデータベースにテーブルが作成されて、Prisma Clientも自動生成されます。便利すぎる。
実際にクエリを書いてみた感想
Prisma Clientを使ったクエリがこれ:
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
// ユーザー全件取得
const users = await prisma.user.findMany()
// 特定のユーザー取得(投稿も含める)
const user = await prisma.user.findUnique({
where: { id: 1 },
include: { posts: true }
})
// 新規ユーザー作成
const newUser = await prisma.user.create({
data: {
email: 'test@example.com',
name: 'テストユーザー',
posts: {
create: {
title: '最初の投稿',
content: 'Prisma最高!'
}
}
}
})
// 条件付き検索
const publishedPosts = await prisma.post.findMany({
where: {
published: true,
author: {
email: { contains: '@example.com' }
}
},
orderBy: { createdAt: 'desc' },
take: 10
})
めっちゃ直感的じゃないですか?
findMany、findUnique、create、update、delete...英語そのまんまなので覚えやすい。
しかもTypeScriptの補完が効くから、whereの中で何が書けるかエディタが教えてくれるんです。これが本当に便利。もうSQLのシンタックスエラーとおさらばです。
Prisma Studioが便利すぎる
Prismaには「Prisma Studio」っていうGUIツールが付いてきます。GUIアンチ教団の私としては使うのは抵抗があるんですが、やっぱり開発中にサクサクTestデータいじれるのは便利でした。
npx prisma studio
これを実行すると、ブラウザでデータベースの中身を確認・編集できるんです。
開発中に「あれ、このデータちゃんと入ってる?」って確認したいときとか、テストデータをサクッと追加したいときとか、めちゃくちゃ捗ります。
phpMyAdminとかみたいな感じだけど、もっとモダンでシンプル。地味に神ツールだと思ってます。
まとめ:SQLと仲良くなれなくても大丈夫!
Prismaに出会ってから、データベース周りの開発が本当に楽になりました。
もちろん、完全にSQLが不要になるわけじゃないです。複雑なクエリとかパフォーマンスチューニングが必要な場面では、やっぱり生SQLを書く必要があるときもあります。
でも、日常的な開発では、ほとんどSQLを書かなくて済むようになりました。型安全だから実行時エラーも減ったし、リファクタリングも怖くない。
「SQLを書きたくない人生」を送ってきた僕にとって、Prismaは救世主でした。
これからもお世話になります。Prismaありがとう。
参考リンク:
Discussion