つい先日dbdocsに入門したという記事を書きましたが、dbdocsではDBマイグレーションの管理などはできないので、ちょっとそこが不満でした。
今回はPrismaに入門して、dbdocsと組み合わせることでGUIでも
Prismaとは
DBクライアント、DBマイグレーション、GUI出力といった機能が一体となったツールです。
Node.jsとTypeScriptを使用しています。
Prisma | Next-generation ORM for Node.js & TypeScript
DBクライアントやDBマイグレーションのプレイグラウンドも用意してあります。親切。
Prisma Playground | Learn the Prisma ORM in your browser
とりあえずマイグレーションを体験してみる
QuickStartに沿ってやっていきましょう。
TypeScriptのプロジェクトは既に作成した前提で、関連するモジュールを追加していきます。
npm install prisma --save-dev
次にprismaの初期化処理を行います。
あんまり凝った構成にすると疲れるので、とりあえずSQLiteを使います。
npx prisma init --datasource-provider sqlite
すると、プロジェクトに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 = "sqlite"
url = env("DATABASE_URL")
}
このファイルに以下のモデルを追加していきます。
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
ではこのモデルを使用してDBマイグレーションファイルを作成します。
npx prisma migrate dev --name init
このコマンドを実行すると、SQLiteのデータベースファイルとマイグレーションファイルが作成されます。
この状態でdbファイルをSQLiteで開こうとしてみましたが、怒られてしまいました。
% sqlite prisma/dev.db
Unable to open database "prisma/dev.db": database disk image is malformed
% sqlite prisma/dev.db
Unable to open database "prisma/dev.db": file is encrypted or is not a database
2回実行してみましたが、何故か別のエラーが出ています。なぜ?
よく確認すると、SQLiteの使用バージョンが2.x.xだったことが分かりました。
% sqlite
SQLite version 2.8.17
Enter ".help" for instructions
sqlite3で実行したらテーブルを読み込むことができました。
%sqlite3 prisma/dev.db
SQLite version 3.37.2 2022-01-06 13:25:41
Enter ".help" for usage hints.
sqlite> .tables # テーブル一覧を表示
Post User _prisma_migrations
しっかりマイグレーションができていますね。
クライアントを使ってみる
次に、ユーザーを作成するスクリプトを実装します。
適当なTypeScriptファイルを作成し、チュートリアルにある通りの実装をします。(index.tsというファイルを作成しました)
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const user = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@prisma.io',
},
})
console.log(user)
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
これを実行してみます。
% npx ts-node index.ts
{ id: 1, email: 'alice@prisma.io', name: 'Alice' }
作成されたようです。
実際にsqliteからも確認してみます。
sqlite> select * from User;
1|alice@prisma.io|Alice
作成されています!
クライアントを使うとかなり楽にモデルを扱えるみたいですね。
dbmlを出力してdbdocsと連携する
では本題です。
こうしてできたスキーマをDBMLとして出力してみます。
これをするためにはまず、prisma-dbml-generatorをインストールしておく必要があります。
以下のコマンドでインストールします。
npm install -D prisma-dbml-generator
続けて、以下のgenerator
セクションをschema.prismaに追加します。
generator dbml {
provider = "prisma-dbml-generator"
// output = "../dbml" // 出力先フォルダ名
// outputName = "database.dbml" // 出力するファイル名
}
最後に以下のコマンドを実行して、dbmlファイルを作成します。
npx prisma generate
コマンドを実行すると、新たにdbml
というディレクトリが作成され、そこにDBMLが格納されています。
中身は以下のようになっています。
//// ------------------------------------------------------
//// THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
//// ------------------------------------------------------
Table User {
id Int [pk, increment]
email String [unique, not null]
name String
posts Post [not null]
}
Table Post {
id Int [pk, increment]
title String [not null]
content String
published Boolean [not null, default: false]
author User [not null]
authorId Int [not null]
}
Ref: Post.authorId > User.id
きちんと作成されていますね。
あとはこれをdbdocsコマンドでビルドします。
(ログインを忘れずに!)
dbdocs build prisma/dbml/schema.dbml --project=prisma_to_dbml
無事にビルドできたので見てみます。
ちゃんと作成されています。
感想
dbdocsと連携ができました。
Prisma標準のGUIツールもあるんですが、ER図を描画できてしかも場所を記憶してくれるので、この辺はdbdocsのほうが使いやすそうだな…と個人的には思いました。
しかしまだ詳しく調べたきれているわけじゃないので、PrismaでER図出力だったらこっちのほうが使いやすいよ!みたいなのがあればコメントお願いします!