2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

初めてのPrisma+MongoDB

Last updated at Posted at 2024-03-29

はじめに

Node.jsのORMであるPrismaを使用してみようと言うことでローカルにMongoDBを立てて使ってみました。

動かした結果、今回はlocalhostで行ってみましたが、MongoDBはdockerで動作させないとinsertで問題がありました。手順に沿って構築しようとしている方はご注意ください。

~~ 最後にdockerで成功した方法を追記しています ~~

MongoDB

Prismaに入る前にMonogDBをlocalhostで構築します。

MongoDBはOSSのDBですが、2018年にSSPLのライセンスに変わっているため、商用利用する方は4.0.3を使用することになります。

今回は商用利用するわけではないため公式から最新版をインストールします。

起動・終了

MongoDBの起動・終了コマンド

# 起動
brew services start mongodb-community@7.0
# 終了
brew services stop mongodb-community@7.0

GUIツール

MonoDB Compass か Visual Studio Codeの拡張機能を使用します。

VSCode拡張機能を使用する場合、Connectionで以下のURLを追加します。

mongodb://localhost:27017/

設定

不要です。

今回は初めからあるadminのDBを使用しますが、自作のDBにしたい場合はDBを追加します。

Prismaがcollectionも作成してくれます。

Prisma

prismaでmongoDBを使用するサンプルのnodeプロジェクトを作成し、Prismaをインストールします。

# nodeプロジェクト作成
npm init prisma-test
# Prismaインストール
npm i @prisma/client
# 初期設定
npx prisma init

prismaフォルダと中にshema.prismaファイルが作られます。
datasourceをmongodbに変更してmodelを追加します。

schema.prisma
generator client {
  provider = “prisma-client-js”
}
datasource db {
  provider = “mongodb”
  url      = env(“DATABASE_URL”)
}
model User {
  id    String @id @default(auto()) @map("_id") @db.ObjectId
  email String @unique
  name  String?
}

init時に.envファイルも作成されているのでDATABASE_URLを設定します。
DB名まで必要です。

.env
DATABASE_URL="mongodb://localhost:27017/admin"

URLの設定は以下を参照

これで準備が整いましたので、以下コマンドを実行します。

npx prisma db push 

MongoDBを見るとadminのDBの中にUserのcollectionが作成されていることが確認できます。

めっちゃ便利ですね。

データの取得

MongoDBのUserのcollectionに1つデータを作成しておきます。

{
    email: "user@example.com",
    name: "user"
}

index.tsを作成して以下のコードを準備します。

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  // ... you will write your Prisma Client queries here

  const allUsers = await prisma.user.findMany()
  console.log(allUsers)
}

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

実行します。

npx ts-node index.ts

結果が返ってきます。

[
  {
    id: '6605ffe06eadfa08ae9250b1',
    email: 'user@example.com',
    name: 'user'
  }
]

データの追加

main関数の中に以下のcreateを追加します。

  await prisma.user.create({
    data: {
      name: 'Rich',
      email: 'hello@prisma.com'
    },
  })

同様に実行するとエラーが発生します。

  4 
  5 async function main() {
  6   // ... you will write your Prisma Client queries here
→ 7   await prisma.user.create(
Prisma needs to perform transactions, which requires your MongoDB server to be run as a replica set. https://pris.ly/d/mongodb-replica-set
    at In.handleRequestError (/Users/xxxx/work/next/prisma-sample/node_modules/@prisma/client/runtime/library.js:122:6854)
    at In.handleAndLogRequestError (/Users/xxxx/work/next/prisma-sample/node_modules/@prisma/client/runtime/library.js:122:6188)
    at In.request (/Users/xxxx/work/next/prisma-sample/node_modules/@prisma/client/runtime/library.js:122:5896)
    at async l (/Users/xxxx/work/next/prisma-sample/node_modules/@prisma/client/runtime/library.js:127:10871)
    at async main (/Users/xxxx/work/next/prisma-sample/index.ts:7:3) {
  code: 'P2031',
  clientVersion: '5.11.0',
  meta: { modelName: 'User' }
}

確認したところMongoDBのレプリカセットが必要とのこと。。。

localhostで設定も可能のようですが、うまくいっていないので初めからDockerを使った方が良かったと言う結論になります。

ORMを使用するとDBアクセスの実装がわかりやすくなりますね。
Prismaは設定も簡単で他のDBもサポートしているので勉強の手間や実装が省けて便利です。

追記

改めて確認しました。
dockerを使うだけでは解決できず、レプリカセットの設定が必要で以下のコマンドで動作確認できました。

#1 - mongo コンテナを起動します
docker run --name mongodb -d -p 27017:27017 mongo mongod --replSet rs0

#2 - mongodb コンテナーが起動して実行されたら、「mongosh」と入力します。
docker exec -it mongodb mongosh

#3 - mongosh 内でレプリカ セットを開始します
rs.initiate({_id: 'rs0', members: [{_id: 0, host: 'localhost:27017'}]})

起動して失敗していたデータ追加を実行すると無事成功しました。


公式ページ

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?