🦁

NextjsからPrisma経由でPostgreSQLに接続する

2025/02/20に公開

https://www.prisma.io/docs/getting-started/quickstart-sqlite
上記を参考に進めていきます。サンプルはsqliteなので適宜読み替えていきます。

まずはセットアップ

npm install prisma --save-dev
npx prisma init --datasource-provider postgresql

PJの中に schema.prisma というファイルができるのでチュートリアルのORM設定を転記する。Azureで動かしてるPostgreSQLがあるのでそちらを使う。

schema.prisma
generator client {
  provider = "prisma-client-js"
}
datasource db {
  provider = "postgresql"
  url      = "postgres://<ID>:<PW>@<URL>:5432/<DB>"
}
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts post[]
}
model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  author    user    @relation(fields: [authorId], references: [id])
  authorId  Int
}

モデルを元にDBをマイグレーションする前に状態を確認して、不要なテーブルはありませんでした。

psql "--host=<URL>" "--port=5432" "--dbname=<DB>" "--username=<ID>" "--set=sslmode=require"

マイグレーションする。合わせてモデルも更新します。

$ npx prisma migrate dev --name init
$ npx prisma generate
Your database is now in sync with your schema.
Running generate... (Use --skip-generate to skip the generators)
✔ Generated Prisma Client (v6.4.0) to ./node_modules/@prisma/client in 71ms

正常に終わったようなのでCLIで確認する。想定通り生成できています。

itsumo=> \dt;
              List of relations
 Schema |        Name        | Type  | Owner  
--------+--------------------+-------+--------
 public | _prisma_migrations | table | testku
 public | post               | table | testku
 public | user               | table | testku
(3 rows)

itsumo=> \d user;
                            Table "public.user"
 Column |  Type   | Collation | Nullable |             Default              
--------+---------+-----------+----------+----------------------------------
 id     | integer |           | not null | nextval('user_id_seq'::regclass)
 email  | text    |           | not null | 
 name   | text    |           |          | 
Indexes:
    "user_pkey" PRIMARY KEY, btree (id)
    "user_email_key" UNIQUE, btree (email)
Referenced by:
    TABLE "post" CONSTRAINT "post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "user"(id) ON UPDATE CASCADE ON DELETE RESTRICT

itsumo=> 

せっかくなのでDB定義を更新します。clientidとuuidを追加して再度マイグレーションします。

model user {
  id    Int     @id @default(autoincrement())
  clientid String
  uuid String
  email String  @unique
  name  String?
  posts post[]
}

clientidは入力した文字列を入れる項目にします。uuidはユーザーを識別するUUIDを作って入れます。uuidはライブラリを利用するためパッケージを追加します。

npm install uuid

ここまでで環境の整備は終わりました。プログラムに手を入れていきます。先ほど作ったパスを取得するAPIの途中でDBにレコードを追加します。

/app/api/users/[slug]/route.ts
import { PrismaClient } from "@prisma/client";
import { NextRequest, NextResponse } from "next/server";
import { v4 as uuidv4 } from 'uuid';

const prisma = new PrismaClient()

export async function GET(req: NextRequest,{params}: {
params: {slug: string }
}) {
  const { slug } = await params;

  // ユーザーの追加funcを呼び出す
  createUser(slug)
  return NextResponse.json({
    "id": slug,
    "message": "データを取得",
  });
}

// ユーザー追加機能
async function createUser(clientid: string) {
  const user = await prisma.user.create({
    data: {
      clientid: clientid,
      uuid: uuidv4(),
      name: 'Alice',
      email: 'alice@prisma.io',
    },
  }).then(async () => {
    await prisma.$disconnect()
  })
  .catch(async (e) => {
    console.error(e)
    await prisma.$disconnect()
    process.exit(1)
  })
}

では、再度動かして http://localhost:3000/api/users/kusakari123456 にアクセスします。

itsumo=> select * from public.user;
 id |      email      |   name    |    clientid    |                 uuid                 
----+-----------------+-----------+----------------+--------------------------------------
  1 | alice@prisma.io | Alice     | kusakari123456 | 4d630bb0-72ab-4a89-bc7c-8fab70f1d998

想定通りレコードが作成されました。パスパラメータがclientidに入り、uuidにも想定通り入っています。次はDBを通した更新や、認証とセッションを使った制御も確認していけたらと考えています。

Discussion