はじめに
PrismaはNode.jsとTypeScript用のORMです。
次のツール群で構成されています。
- Prisma Client
- Prisma Migrate
- Prisma Studio
https://www.prisma.io/docs/getting-started/setup-prisma/start-from-scratch-typescript-postgres に記載されている手順で、プロジェクト作成を作成しPrismaを触ってみました。
※ Prisma Studioの部分に関しては、試していないので記載していません。
実行環境
バージョン | |
---|---|
npm | 6.14.7 |
node | v14.7.0 |
prisma | 2.25.0 |
@prisma/client | 2.25.0 |
プロジェクト作成
$ mkdir hello-prisma
$ cd hello-prisma
$ npm init -y
$ npm install prisma typescript ts-node @types/node --save-dev
tsconfig.json
を作成して、以下の内容を記載します。
{
"compilerOptions": {
"sourceMap": true,
"outDir": "dist",
"strict": true,
"lib": ["esnext"],
"esModuleInterop": true
}
}
以下のコマンドを実行すると、.env
ファイルとprisma/schema.prisma
が作成されます。
$ npx prisma init
データベースの準備
データベースはPostgreSQLを使用するので、Dockerを使ってPostgreSQLの準備をします。
(ここは公式サイトには記載がない内容です)
docker-compose.yml
を作成し、docker compose up -d
を実行する。
version: "3"
services:
db:
image: postgres:13.3
environment:
POSTGRES_USER: sample
POSTGRES_PASSWORD: password
ports:
- 5432:5432
volumes:
- postgres:/var/lib/postgresql
volumes:
postgres:
データベースに接続する
PostgreSQLを使用するので、自動生成されたprisma/schema.prisma
のままで変更はありません。
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
データベースへの接続URLは.env
ファイルから取得しているので、Dockerで起動したPostgreSQLに接続できるように変更します。
URLはpostgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA
の形式で設定します。
USER
とPASSWORD
は、docker-compose.yml
で指定したPOSTGRES_USER
とPOSTGRES_PASSWORD
の値になります。
DATABASE_URL="postgresql://sample:password@localhost:5432/mydb?schema=public"
データベースとテーブルの作成
prisma/schema.prisma
に作成するテーブルの定義を追記し、migrateを実行します。
model Post {
id Int @default(autoincrement()) @id
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
model Profile {
id Int @default(autoincrement()) @id
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model User {
id Int @default(autoincrement()) @id
email String @unique
name String?
posts Post[]
profile Profile?
}
$ npx prisma migrate dev --name init
prisma/migrations/20210622135843_init/migration.sql
が作成されます。
Prisma Clientをインストール
$ npm install @prisma/client
クエリの実行
Prisma Clientを生成したので、スクリプトからデータベースに対してクエリを実行します。
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const allUsers = await prisma.user.findMany()
console.log(allUsers)
}
main()
.catch((e) => {
throw e
})
.finally(async () => {
await prisma.$disconnect()
})
index.ts
を実行してデータベースからデータを取得してみます。
$ npx ts-node index.ts
[]
User
テーブルの全レコードを取得するクエリを実行していますが、まだ何もデータが登録されていないので[]
が出力されます。
User
/Post
/Profile
にデータを作成してから、取得クエリを実行します。
async function main() {
await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@prisma.io',
posts: {
create: { title: 'Hello World' },
},
profile: {
create: { bio: 'I like turtles' },
},
},
})
const allUsers = await prisma.user.findMany({
include: {
posts: true,
profile: true,
},
})
console.dir(allUsers, { depth: null })
}
$ npx ts-node index.ts
[
{
id: 1,
email: 'alice@prisma.io',
name: 'Alice',
posts: [
{
id: 1,
createdAt: 2021-06-22T14:15:54.213Z,
updatedAt: 2021-06-22T14:15:54.214Z,
title: 'Hello World',
content: null,
published: false,
authorId: 1
}
],
profile: { id: 1, bio: 'I like turtles', userId: 1 }
}
]
Post
テーブルのpublished
カラムをtrue
に更新します。
async function main() {
const post = await prisma.post.update({
where: { id: 1 },
data: { published: true },
})
console.log(post)
}
$ npx ts-node index.ts
{
id: 1,
createdAt: 2021-06-22T14:15:54.213Z,
updatedAt: 2021-06-22T14:21:05.080Z,
title: 'Hello World',
content: null,
published: true,
authorId: 1
}
おまけ:実行されるSQLを確認する
実際にどういうSQLが発行されているのか知りたい場合は、ログ出力すれば確認できます。
PrismaClient
のインスタンスを生成する際の引数に{ log: ['query']}
を渡すと、実行されるSQLのログが出力されます。
- const prisma = new PrismaClient()
+ const prisma = new PrismaClient({ log: ['query']})
$ npx ts-node index.ts
prisma:query SELECT "public"."User"."id", "public"."User"."email", "public"."User"."name" FROM "public"."User" WHERE 1=1 OFFSET $1
[ { id: 1, email: 'alice@prisma.io', name: 'Alice' } ]
さいごに
基本的に公式サイトに記載されている通りの手順で進めたので、詰まるところはありませんでした。
今回使われていないPrisma ClientのAPIがまだまだたくさんあるので、色々触っていこうと思います。