Prisma
In MBC CQRS Serverless, we use prisma as an ORM. It helps developers be more productive when working with databases.
A common scenario when working with Prisma is needing to make changes to the database, such as creating tables, updating fields in tables, etc. Follow these steps:
- Update prisma/schema.prisma file.
- For local development, create and apply migrations with command npm run migrate:dev.
Setup
PrismaService
The mbc new CLI command generates a PrismaService in src/prisma/prisma.service.ts. It extends PrismaClient and integrates with NestJS's module lifecycle:
// 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
// Set explicitConnect: true in prismaServiceOptions only if you need startup connection
}
}
Register in AppModule
Register PrismaModule as a global module in src/main.module.ts so PrismaService is available in all modules without re-importing:
import { Module } from '@nestjs/common';
import { PrismaModule } from './prisma';
@Module({
imports: [
PrismaModule.forRoot({
isGlobal: true, // Make PrismaService available everywhere without re-importing
prismaServiceOptions: {
explicitConnect: false, // Recommended for Lambda: lazy connection per invocation
prismaOptions: {
log: process.env.NODE_ENV !== 'local' ? ['error'] : ['info', 'error', 'warn', 'query'],
},
},
}),
// ... other modules
],
})
export class MainModule {}
Set explicitConnect: false (the default) for Lambda functions. Prisma establishes the RDS connection lazily on the first query and does not hold it between invocations. Use RDS Proxy in production to pool connections across concurrent Lambdas and prevent connection exhaustion.
Migration Scripts
| Command | When to use | What it does |
|---|---|---|
npm run migrate:dev | Local development only | Creates a new Prisma migration file and applies it to the local RDS database. Use this when you change schema.prisma. |
npm run migrate | Local setup and CI | Applies existing Prisma migrations to RDS (without creating new ones), then runs DynamoDB table migration. Use this after cloning or pulling. |
npm run migrate:ddb | DynamoDB only | Creates or updates DynamoDB tables defined in prisma/dynamodbs/*.json without touching the RDS schema. |
For local development, please make sure to set the correct DATABASE_URL environment variable.
# Example
DATABASE_URL="mysql://root:RootCqrs@localhost:3306/cqrs"
You could view prisma-client documentation for more information
Design table convention
When creating an RDS table that maps to a DynamoDB table, ensure you add the necessary fields and indexes to the RDS table accordingly. The cpk/csk fields store the original command table keys (used to link back to the DynamoDB command record). Include them when you need full traceability from RDS to DynamoDB; omit them if you only need the data table keys (pk/sk).
model YourEntity {
id String @id
cpk String // Command PK
csk String // Command SK
pk String // Data PK
sk String // Data 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
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
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])
}
Related Documentation
- Database Selection Guide - Choosing between DynamoDB and RDS
- Data Sync Handler Examples - Sync DynamoDB data to RDS
- Environment Variables - Database connection configuration
- Deployment Guide - Database migration in deployment