Typescriptで動作するDBのマイグレーションツールPrismaを触ってみた
Prisma
いくつかマイグレーションツール探していてなんか良いのがなかった
最悪、sqlでどうにかしようかなぁと思っていた。
お試し環境
node16のdockerコンテナ
docker-compose
version: "3" services: # backend backedn: # コンテナ名 container_name: node-dev # build image: node:16 # コンテナの中に入る tty: true # 他のコンテナ起動後に起動するように制御 depends_on: - db # ボリューム volumes: - "./app" # WORKDIR working_dir: /app # 環境変数 environment: TZ: "Asia/Tokyo" # DBサーバ db: # コンテナ名 container_name: db # build image: mysql # 環境設定 environment: TZ: Asia/Tokyo MYSQL_ROOT_USER: root MYSQL_ROOT_PASSWORD: password MYSQL_DATABASE: sample1 MYSQL_USER: app MYSQL_PASSWORD: password # コンテナの中に入る tty: true # ボリューム volumes: - mysql_data:/var/lib/mysql # ポート開放 ports: - 3306:3306 # 名前付きボリュームをdockerホストの管理下で作成 volumes: # mysql_data: {}
build, up
docker-compose build docker-compose run --rm backend bash
↓
# node -v v16.13.0 # npm -v 8.1.0 #
手順
プロジェクト初期化
# npm init -y Wrote to /app/package.json: { "name": "app", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC" } #
関連パッケージをインストール
npm install --save typescript npm install --save @types/node npm install --save ts-node npx tsc --init npm install --save express npm install --save @types/express npm install --save-dev prisma npm install --save @prisma/client
↓
# cat package.json { "name": "app", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "@prisma/client": "^3.5.0", "@types/express": "^4.17.13", "@types/node": "^16.11.9", "express": "^4.17.1", "ts-node": "^10.4.0", "typescript": "^4.5.2" }, "devDependencies": { "prisma": "^3.5.0" } } #
prismaの初期化
npx prisma init
↓
. |-- package-lock.json |-- package.json |-- prisma | `-- schema.prisma `-- tsconfig.json
.env
、prisma/schema.prisma
が生成されるため、DBの情報を修正する
.env
DATABASE_URL="mysql://root:password@db:3306/sample1"
prisma/schema.prisma
generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") }
モデルを作成する
prisma/schema.prisma
generator client { provider = "prisma-client-js" } datasource db { provider = "mysql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) email String @unique name String? @@map("users") }
マイグレーション実行
npx prisma migrate dev --name init
↓
新規の場合はmigrations
ディレクトリが作成され、SQLファイルができる
migrations/ └─ 20211120075456_init/ └─ migration.sql
DB構成
適当なデータを準備
INSERT INTO users ( `email`, `name` ) VALUES ('test1@test.com', 'test1'), ('test2@test.com', 'test2'), ('test3@test.com', 'test3') ;
サンプルコード
index.ts
import { PrismaClient } from '@prisma/client' const prisma = new PrismaClient() async function main() { const allUsers = await prisma.user.findMany({}) console.dir(allUsers, { depth: null }) } main() .catch((e) => { throw e }) .finally(async () => { await prisma.$disconnect() })
↓
npx ts-node index.ts
↓
[ { id: 1, email: 'test1@test.com', name: 'test1' }, { id: 2, email: 'test2@test.com', name: 'test2' }, { id: 3, email: 'test3@test.com', name: 'test3' } ]
うん、いい感じ
所感
最初はSequelize
でいく予定でしたがテーブル名を別名で定義するところとかがうまくできなくて
困っていました。
こちらは結構わかりやすい感じ
ゴリゴリ対応は最悪SQL直がきにしかないかもですがシンプルな構成の場合はやりやすいかも
次はSeedを試す
参考
Prisma - Next-generation Node.js and TypeScript ORM for Databases