😅

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
})

めっちゃ直感的じゃないですか?

findManyfindUniquecreateupdatedelete...英語そのまんまなので覚えやすい。

しかもTypeScriptの補完が効くから、whereの中で何が書けるかエディタが教えてくれるんです。これが本当に便利。もうSQLのシンタックスエラーとおさらばです。

Prisma Studioが便利すぎる

Prismaには「Prisma Studio」っていうGUIツールが付いてきます。GUIアンチ教団の私としては使うのは抵抗があるんですが、やっぱり開発中にサクサクTestデータいじれるのは便利でした。

npx prisma studio

これを実行すると、ブラウザでデータベースの中身を確認・編集できるんです。

開発中に「あれ、このデータちゃんと入ってる?」って確認したいときとか、テストデータをサクッと追加したいときとか、めちゃくちゃ捗ります。

phpMyAdminとかみたいな感じだけど、もっとモダンでシンプル。地味に神ツールだと思ってます。

まとめ:SQLと仲良くなれなくても大丈夫!

Prismaに出会ってから、データベース周りの開発が本当に楽になりました。

もちろん、完全にSQLが不要になるわけじゃないです。複雑なクエリとかパフォーマンスチューニングが必要な場面では、やっぱり生SQLを書く必要があるときもあります。

でも、日常的な開発では、ほとんどSQLを書かなくて済むようになりました。型安全だから実行時エラーも減ったし、リファクタリングも怖くない。

「SQLを書きたくない人生」を送ってきた僕にとって、Prismaは救世主でした。

これからもお世話になります。Prismaありがとう。


参考リンク:

Discussion