Files
Kokorone/.agents/skills/prisma-client-api/references/constructor.md
T
Jeffery f44200f543 feat: 完成 B 群組 — 資料層與核心領域模型
- 導入 Prisma 7.9.1 + SQLite(better-sqlite3 driver adapter),prisma.config.ts 管理連線設定
- 完整資料模型:User/Work/Character/CharacterAlias/EpisodicMemory/SemanticMemory/
  ProceduralRule/EmotionState/Relationship/SentimentLedgerEntry
- packages/db:Prisma Client 存取層(ESM,因 Prisma 7 產出的 generated client 僅支援 ESM)
- apps/api 隨之改為 ESM 以相容 packages/db
- packages/shared:新增角色/記憶/情緒/關係共用型別,api 與 web 皆從此匯入
- prisma/seed.ts:建立測試使用者與元氣型測試角色,含完整關係帳本與記憶種子資料
- apps/api:新增 GET /characters
- scripts/smoke/B.mjs:驗證資料表齊全、API 讀出種子角色、關係與記憶可寫入讀出
- 保留 Prisma 官方隨 CLI 附的 agent skill 文件(.agents/skills 等),供後續群組查閱

npm run restart && npm run smoke -- B 皆通過(B-V),A 群組冒煙測試無回歸。
2026-08-13 09:43:15 +08:00

222 lines
4.8 KiB
Markdown

# PrismaClient Constructor
Configure Prisma Client when instantiating.
## Basic Instantiation
```typescript
import { PrismaClient } from '../generated/client'
import { PrismaPg } from '@prisma/adapter-pg'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL
})
const prisma = new PrismaClient({ adapter })
```
## Constructor Options
### adapter (Required for the SQL provider workflow)
Driver adapter instance:
```typescript
import { PrismaPg } from '@prisma/adapter-pg'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL
})
const prisma = new PrismaClient({ adapter })
```
### accelerateUrl (For Accelerate users)
```typescript
import { withAccelerate } from '@prisma/extension-accelerate'
const prisma = new PrismaClient({
accelerateUrl: process.env.DATABASE_URL, // prisma:// URL
}).$extends(withAccelerate())
```
### log
Configure logging:
```typescript
const prisma = new PrismaClient({
adapter,
log: ['query', 'info', 'warn', 'error'],
})
```
#### Log levels
| Level | Description |
|-------|-------------|
| `query` | All SQL queries |
| `info` | Informational messages |
| `warn` | Warnings |
| `error` | Errors |
#### Log to events
```typescript
const prisma = new PrismaClient({
adapter,
log: [
{ level: 'query', emit: 'event' },
{ level: 'error', emit: 'stdout' },
],
})
prisma.$on('query', (e) => {
console.log('Query:', e.query)
console.log('Duration:', e.duration, 'ms')
})
```
### errorFormat
Control error formatting:
```typescript
const prisma = new PrismaClient({
adapter,
errorFormat: 'pretty', // 'pretty' | 'colorless' | 'minimal'
})
```
### comments
Attach SQL commenter plugins for observability, tracing, or query insights:
```typescript
import { PrismaClient } from '../generated/client'
import { PrismaPg } from '@prisma/adapter-pg'
import { prismaQueryInsights } from '@prisma/sqlcommenter-query-insights'
import { queryTags, withQueryTags } from '@prisma/sqlcommenter-query-tags'
import { traceContext } from '@prisma/sqlcommenter-trace-context'
const prisma = new PrismaClient({
adapter: new PrismaPg(process.env.DATABASE_URL!),
comments: [prismaQueryInsights(), traceContext(), queryTags()],
})
await withQueryTags({ route: '/api/users', requestId: 'req-123' }, () =>
prisma.user.findMany(),
)
```
Use `comments` only for SQL providers. This is the clean way to add trace or query-shape metadata without changing your query calls.
### transactionOptions
Default transaction settings:
```typescript
const prisma = new PrismaClient({
adapter,
transactionOptions: {
maxWait: 5000, // Max wait to acquire transaction (ms)
timeout: 10000, // Max transaction duration (ms)
isolationLevel: 'Serializable',
},
})
```
### queryPlanCacheMaxSize
Use `queryPlanCacheMaxSize` to limit the in-memory query-plan cache:
```typescript
const prisma = new PrismaClient({
adapter,
queryPlanCacheMaxSize: 2_000,
})
```
The value must be a non-negative integer. Set it to `0` to disable query-plan caching; omit it to use Prisma's default. Treat this as a process-local memory/performance control, not a database prepared-statement setting.
## Singleton Pattern
Prevent multiple client instances in development:
```typescript
// lib/prisma.ts
import { PrismaClient } from '../generated/client'
import { PrismaPg } from '@prisma/adapter-pg'
const globalForPrisma = globalThis as unknown as {
prisma: PrismaClient | undefined
}
function createPrismaClient() {
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL!
})
return new PrismaClient({ adapter })
}
export const prisma = globalForPrisma.prisma ?? createPrismaClient()
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
}
```
## Next.js Pattern
```typescript
// lib/prisma.ts
import { PrismaClient } from '@/generated/client'
import { PrismaPg } from '@prisma/adapter-pg'
const createAdapter = () => new PrismaPg({
connectionString: process.env.DATABASE_URL!
})
const prismaClientSingleton = () => {
return new PrismaClient({ adapter: createAdapter() })
}
declare const globalThis: {
prismaGlobal: ReturnType<typeof prismaClientSingleton>
} & typeof global
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton()
export default prisma
if (process.env.NODE_ENV !== 'production') {
globalThis.prismaGlobal = prisma
}
```
## Query Events
Listen to query events:
```typescript
const prisma = new PrismaClient({
adapter,
log: [{ level: 'query', emit: 'event' }],
})
prisma.$on('query', (e) => {
console.log('Query:', e.query)
console.log('Params:', e.params)
console.log('Duration:', e.duration)
})
```
## Log Events
```typescript
prisma.$on('info', (e) => console.log(e.message))
prisma.$on('warn', (e) => console.warn(e.message))
prisma.$on('error', (e) => console.error(e.message))
```