Prisma
MBC CQRS サーバーレスでは、ORM として Prisma を使用します。これは、開発者がデータベースを操作する際の生産性を高めるのに役立ちます。
Prisma を使用する場合の一般的なシナリオでは、テーブルの作成、テーブル内のフィールドの更新など、データベースに変更を加える必要があります。次の手順を行います。
- prisma/schema.prisma ファイルを更新します。
- ローカル開発の場合は、npm run migrate:dev コマンドを実行してマイグレーションファイルを作成し、適用します。
セットアップ
PrismaService
mbc new CLIコマンドはsrc/prisma/prisma.service.tsにPrismaServiceを生成します。PrismaClientを継承し、NestJSのモジュールライフサイクルと統合されています:
// src/prisma/prisma.service.ts (generated by CLI)
import { Injectable, Logger, OnModuleInit, Inject, Optional } from '@nestjs/common';
import { Prisma, PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService
extends PrismaClient<Prisma.PrismaClientOptions, 'query' | 'error'>
implements OnModuleInit
{
private readonly logger = new Logger(PrismaService.name);
async onModuleInit() {
// Lazy connection by default — avoids holding connections between Lambda invocations (デフォルトはレイジー接続 — Lambda呼び出し間で接続を保持しない)
// Set explicitConnect: true in prismaServiceOptions only if you need startup connection (起動時に接続が必要な場合のみprismaServiceOptionsでexplicitConnect: trueを設定)
}
}
AppModuleへの登録
PrismaModuleをグローバルモジュールとしてsrc/main.module.tsに登録することで、PrismaServiceを再インポートなしですべてのモジュールで利用できます:
import { Module } from '@nestjs/common';
import { PrismaModule } from './prisma';
@Module({
imports: [
PrismaModule.forRoot({
isGlobal: true, // Make PrismaService available everywhere without re-importing (再インポートなしで全モジュールからPrismaServiceを利用可能にする)
prismaServiceOptions: {
explicitConnect: false, // Recommended for Lambda: lazy connection per invocation (Lambda推奨: 呼び出し毎のレイジー接続)
prismaOptions: {
log: process.env.NODE_ENV !== 'local' ? ['error'] : ['info', 'error', 'warn', 'query'],
},
},
}),
// ... other modules (その他のモジュール)
],
})
export class MainModule {}
Lambda関数ではexplicitConnect: false(デフォルト)を設定してください。Prismaは最初のクエリ時にRDS接続を遅延確立し、呼び出し間で接続を保持しません。本番環境では、RDS Proxyを使用して並行Lambdaにわたる接続をプールし、接続枯渇を防いでください。
マイグレーションスクリプト
| コマンド | 使用タイミング | 処理内容 |
|---|---|---|
npm run migrate:dev | ローカル開発のみ | 新しいPrismaマイグレーションファイルを作成し、ローカルRDSデータベースに適用します。schema.prismaを変更した際に使用してください。 |
npm run migrate | ローカルセットアップおよびCI | 既存のPrismaマイグレーションをRDSに適用し(新規作成なし)、その後DynamoDBテーブルのマイグレーションを実行します。クローンまたはプル後に使用してください。 |
npm run migrate:ddb | DynamoDBのみ | prisma/dynamodbs/*.jsonで定義されたDynamoDBテーブルを作成または更新します。RDSスキーマには影響しません。 |
ローカル開発の場合は、正しい「DATABASE_URL」環境変数を設定してください。
# 例
DATABASE_URL="mysql://root:RootCqrs@localhost:3306/cqrs"
詳細については、prisma-client ドキュメント をご覧ください。
テーブル設計の規則
DynamoDB テーブルにマップする RDS テーブルを作成するときは、必要なフィールドとインデックスをそれに応じて RDS テーブルに追加してください。cpk/csk フィールドにはコマンドテーブルの元のキーを格納します(DynamoDB コマンドレコードへの参照用)。RDS から DynamoDB への完全なトレーサビリティが必要な場合は含めてください。データテーブルのキー(pk/sk)だけで十分な場合は省略できます。
model YourEntity {
id String @id
cpk String // Command PK (コマンド用PK)
csk String // Command SK (コマンド用SK)
pk String // Data PK (データ用PK)
sk String // Data SK (データ用SK)
tenantCode String @map("tenant_code") // Tenant code (テナントコード)
seq Int @default(0) // Sort order, uses sequence feature (並び順、採番機能を使用)
code String // Record code (レコードコード)
name String // Record name (レコード名)
version Int // Version (バージョン)
isDeleted Boolean @default(false) @map("is_deleted") // Deleted flag (削除フラグ)
createdBy String @default("") @map("created_by") // Created by (作成者)
createdIp String @default("") @map("created_ip") // Created IP, supports IPv6 (作成IP、IPv6対応)
createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(0) // Created at (作成日時)
updatedBy String @default("") @map("updated_by") // Updated by (更新者)
updatedIp String @default("") @map("updated_ip") // Updated IP, supports IPv6 (更新IP、IPv6対応)
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamp(0) // Updated at (更新日時)
// domain-specific properties (ドメイン固有のプロパティ)
// relations (リレーション)
// index (インデックス)
@@unique([cpk, csk])
@@unique([pk, sk])
@@unique([tenantCode, code])
@@index([tenantCode, name])
}
関連ドキュメント
- データベース選択ガイド - DynamoDBとRDSの選択
- データ同期ハンドラー例 - DynamoDBデータのRDSへの同期
- 環境変数 - データベース接続設定
- デプロイガイド - デプロイ時のデータベース移行