abeshi blog
カテゴリーで検索

prismaの環境構築ハンズオン!

2022年1月28日



今回はprismaをはじめて導入して、エラー等も途中出たのでメモ

Prismaとは



TypeScript制のORMです。
Rubyでいうactive recordみたいな感じです。


今回は公式ドキュメントに沿って進めていきます。


前提


データベースはpostgreSqlを使用
expressでプロジェクトを立ち上げている程で進めていきます


Install


npm install prisma typescript ts-node @types/node --save-dev



まずは必要パッケージをinstallします。

// tsconfig.json

{
  "compilerOptions": {
    "sourceMap": true,
    "outDir": "dist",
    "strict": true,
    "lib": ["esnext"],
    "esModuleInterop": true
  }
}



tsconfig.jsonを作成し上記をコピペします。(今回はprismaに焦点を当てているのでtsconfig.jsonに関しては割愛します)

npx prisma
npx prisma init


上記のコマンドを打つとschema.prismaと .envファイルが作成されます。

schema.prisma ... データベースとの接続、モデルの定義などをしていくファイル
.env ... 環境変数用のファイル

データベースと接続する



今回は簡単にローカルでdbを立てて、そこと接続していきます。
ローカルのdbの作成方法に関しては下記の記事に書いてあるのでご参考までに。
https://abeshi-blog.com/blog/7logsp08hm3


// schema.prisma

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}



schema.prismaにこのようなコードが元々書かれているかと思います。

env("DATABASE_URL")



こちらで環境変数を読み込んでいるので.envファイルにDATABASE_URLを定義していきます。

DATABASE_URL="postgresql://USER:PASSWORD@localhost:5432/DATABASE_NAME?schema=public"


USER ... ユーザー名
PASSWORD ... パスワード
DATABASE_NAME ... データベース名を入れます。

DBのURLに関しては使うORMなどによっても違うのでご注意を。
localhostの場合何もいじっていなければポートは5432です。


モデルを定義する



今回は公式ドキュメントに沿ってユーザー、投稿、プロフィールのmodelを定義していきます。


// schema.prisma

model Post {
  id               Int              @id @default(autoincrement())
  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          @id @default(autoincrement())
  bio    String?
  user   User      @relation(fields: [userId], references: [id])
  userId Int        @unique
}

model User {
  id         Int         @id @default(autoincrement())
  email   String   @unique
  name   String?
  posts   Post[]
  profile  Profile?
}



モデルを定義したら下記のコマンドを実行します。

npx prisma migrate dev --name init



上記のコマンドでsqlをデータベースに向けて実行できるようにしてくれます。

※はじめこちらのコマンドを実行した際、下記のエラーが出ました

Error: P3014

Prisma Migrate could not create the shadow database. Please make sure the database user has permission to create databases. Read more about the shadow database 



原因としては権限まわりだそうです。
postgresqlの権限を確認するためにはデータベースを起動して\duコマンドを使います。

こちらで権限周りを確認することができます。

手っ取り早いのは該当のユーザーをSuperuserにすることです。

ALTER ROLE 名前 CREATEROLE;



上記のコマンドでuserのroleを変更することができます。


npx prisma migrate dev --name init


でマイグレートを実行するとmigration.sqlとmigration_lock.tomの二つのファイルが作成されます。

そしてこれによりmodelに定義した3つのテーブルを作成することができるようになります!!!


データベースのクエリを作成していく



ここからはprisma clientを使っていくのでまずこちらをinstallします。

npm install --save @prisma/client



これでindex.tsを書き換えていきます

// index.ts

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient();

async function main() {

  await prisma.user.create({
    data: {
      name: "Alice",
      email: "alice@prisma.io",
      posts: {
        create: { title: "HELLO WORLD" }
      },
      profile: {
        create: { bio: "I like apple" }
      },
    },
  })

  const allUsers = await prisma.user.findMany({
    include: {
      posts: true,
      profile: true
    }
  })
  console.log(allUsers)
}

main()
  .catch((e) => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })




まずはPrismaClientをimportしprismaの変数に宣言します。

main以下をコピペして下記のコマンドを実行しましょう!!

npx ts-node index.ts



するとconsole.log(allUsers)をしているので

下記がコンソールに出るかと思います。

[
  {
    id: 3,
    email: 'alice@prisma.io',
    name: 'Alice',
    posts: [ [Object] ],
    profile: { id: 2, bio: 'I like apple', userId: 3 }
  }
]




つまりUser, Profile, Postsテーブルにレコードが追加されたことがわかります。


prisma.テーブル名.createで追加のコマンドに
prisma.テーブル名.findManyで一覧を取得しています。
includeオプションではposts, profileを含むかを表しています。
こちら表示しないとレスポンスはid, email, nameのみになります。



次にpostsの更新をしてみます。


main関数の中身を下記に変更します


async function main() {

  // await prisma.user.create({
  //   data: {
  //     name: "Alice",
  //     email: "alice@prisma.io",
  //     posts: {
  //       create: { title: "HELLO WORLD" }
  //     },
  //     profile: {
  //       create: { bio: "I like apple" }
  //     },
  //   },
  // })

  // const allUsers = await prisma.user.findMany({
  //   include: {
  //     posts: true,
  //     profile: true
  //   }
  // })

  const post = await prisma.post.update({
    where: { id: 1 },
    data: { published: true }
  })
  console.log(post)
}



ts-node index.ts



{
  id: 1,
  createdAt: 2022-01-28T01:26:37.747Z,
  updatedAt: 2022-01-28T01:53:17.425Z,
  title: 'HELLO WORLD',
  content: null,
  published: true,
  authorId: 1
}



上記が返ってくることが確認できると思います。
publishedがdefaultのfalseからtrueに更新されているのがわかると思います。


prismaの触りは掴めたと思います。
あとは公式ドキュメントをガチャガチャいじっていきましょう!
お疲れさまでした!!!
https://www.prisma.io/