次世代ORM Prisma  スキーマから型安全なコード自動生成

# Prismaとは
PrismaはNode.jsとTypeScript用のオープンソースORMです。
なので、Prismaではデータベースに接続、マイグレーションでテーブル作成、データの投入を実現できます。
また、schema.prismaでスキーマ定義からTypeScriptのコードを生成することも可能です。

# 特徴
Prismaには次の3つの特徴があります。
### ①Prisma Client
Prisma Clientは自動生成されたTypeScriptのメソッドを呼び出すことができます。
このメソッドにはcreate、deleteなど様々なメソッドがありそれらを利用し、型安全なデータベース操作を可能にすることができます。
Sequelize、TypeORMなどのSQLクエリビルダなど従来のORMの代替として注目されています。

### ②Prisma Migrate
Prisma Migrateではschema.prismaで定義されたテーブル情報を元にデータベースにテーブルを作成します。

### ③Prisma Studio
Prisma Studioではブラウザ上でテーブルデータやリレーションの関係確認、テーブル操作ができます。
SQLクライアントのようなものです。

# Prismaがサポートしているデータベース
+ PostgreSQL
+ MySQL
+ MariaDB
+ SQLite
+ AWS Aurora
+ AWS Aurora サーバーレス
+ Azure SQL
+ MongoDB
+ Microsoft SQL Server
+ CockroachDB


本記事ではprismaを使ったテーブル作成〜データの投入方法などをご紹介します。
# 準備
```
フォルダを作成します。

mkdir test-prisma
cd test-prisma

```

noed.jsで環境を構築します。

```
yarn add @nestjs/cli
yarn nest new backend

cd backend
```

Prismaを導入します。

```
yarn add -D prisma typescript ts-node @types/node
yarn prisma init
```

backend/prisma配下にschema.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 = "postgresql"
  url      = env("DATABASE_URL")
}

```

データベースと接続するために、DBサーバーをDockerで構築します。
backend配下にdocker-compose.ymlファイルを作成します。

```docker-compose.yml
version: "3"

volumes:
  db-data:

services:
  db:
    image: postgres:14
    container_name: nest-db
    volumes:
      - db-data:/var/lib/postgresql/local_db/data
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password

```

コンテナを起動します。

```terminal 
docker compose up -d
```

DBコンテンナが立ち上がれば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 = "postgresql"
  url      = "postgresql://postgres:password@localhost:5432/local_db?schema=public"　-->修正
}

```

# テーブルの作成
テーブル追加のため、スキーマファイルをTypeScript形式で編集していきます。
記述方法詳細に関しては公式リファレンスを参照してください。

https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference


```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 = "postgresql"
  url      = "postgresql://postgres:password@localhost:5432/local_db?schema=public"
}

--追加--
model Todo {
 id           String    @id @default(uuid())
 name         String
 dueDate      String
 status       String
 memo         String
 createdAt    DateTime  @default(now()) @map("created_at")
 updatedAt    DateTime  @updatedAt @map("updated_at")

 @@map("todo")
}


```

実際にテーブルを作成していきましょう。
コマンドを実行するとテーブルが作成され、prisma/migrations配下に/migration.sqlが自動生成されます。

```
yarn prisma migrate dev --name init
```

# テストデータ挿入

```backend/prisma/seed/parent.ts

import { PrismaClient } from '@prisma/client';
import { prismaCreateTodo } from './todo';


const prisma = new PrismaClient();

const main = async () => {
  await prismaCreateTodo();
};

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
});
```


テストデータ投入する処理はmain関数内で呼び出しています。

```backend/prisma/seed/parent.ts
 await prismaCreateTodo(); --> これ
```

こちらの関数はseed配下のtodo.tsで定義しています。
テーブル毎にseedファイルを作成し(todo.tsみたいな)、main関数内で呼ぶことでテーブルのデータ毎にseedファイルを分割することができます。


こちらが実際のテストデータの定義と投入処理になります。
PrismaClientで定義されているcreate関数を実行し、データの投入をしています。

```backend/prisma/seed/todo.ts

import { PrismaClient, Prisma, Todo } from '@prisma/client';
const prisma = new PrismaClient();


const todoData: Todo[] = [
  {
    id: '1',
    name: 'todo',
    dueDate: '2022-08-20',
    status: 'done',
    memo: '不死鳥',
    createdAt: new Date('2022-01-31T04:34:22+09:00'),
    updatedAt: new Date('2022-01-31T04:34:22+09:00'),
  },
];

export const prismaCreateTodo = async () => {
  const todos = [];
  for (const todo of todoData) {
    const createPosts = prisma.todo.create({
      data: todo,
    });
    todos.push(createPosts);
  }
  prisma.$transaction(todos);
};

```

それではデータを投入するコマンドを叩きましょう。
その前にコマンドを叩きやすくするためにpackage.jsonを修正しましょう。

```backend/package.json

"prisma": {
   "seed": "ts-node prisma/parent.ts"
}

```

ターミナルのbackend/でコマンドを叩きます。
すると、、、、、

```
yarn prisma db seed
```

データが投入されていることが確認できます。
こちらはsqlclientでDBに接続して確認していますが、特徴にもあるPrisma Studioで確認してみましょう！

![スクリーンショット 2022-08-14 22.29.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/479c3f78-5bc2-466a-c4ab-2ea4376a0a71.png)



# Prisma Studioで確認
prismaがインストールされていれば、コマンドを叩くことで確認用にローカルサーバーが立ち上がります。

```
yarn prisma studio

Environment variables loaded from .env
Prisma schema loaded from prisma/schema.prisma
Prisma Studio is up on http://localhost:5555

```

SQLクライアントをインストールせずにテーブル内のデータ操作がブラウザで可能なので、めちゃくちゃ便利です。
Filterでデータの抽出やデータの削除、追加は手動で行えますが、クエリの実行はできないのでご注意ください！

![スクリーンショット 2022-08-14 23.00.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661515/d5e5b39e-2e96-a655-ee9a-bdd3aee104f9.png)


以上！閲覧いただきありがとうございました！

# 【参考文献】

https://medium.com/sliit-foss/a-next-generation-orm-prisma-3c3f2b46bd5b

https://www.prisma.io/docs/reference/database-reference/supported-databases

https://www.prisma.io/docs/reference/api-reference/prisma-schema-reference

https://www.prisma.io/docs/concepts/more/comparisons/prisma-and-typeorm