Files
Kokorone/.agents/skills/prisma-client-api/references/relations.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

309 lines
4.3 KiB
Markdown

# Relation Queries
Query and modify related records.
## Include Relations
Load related records:
```typescript
const user = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: true,
profile: true
}
})
```
### Filtered include
```typescript
const user = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: {
where: { published: true },
orderBy: { createdAt: 'desc' },
take: 5,
select: { id: true, title: true }
}
}
})
```
### Nested include
```typescript
const user = await prisma.user.findUnique({
where: { id: 1 },
include: {
posts: {
include: {
comments: {
include: { author: true }
}
}
}
}
})
```
## Select Relations
```typescript
const user = await prisma.user.findUnique({
where: { id: 1 },
select: {
name: true,
posts: {
select: { title: true }
}
}
})
```
## Nested Writes
### Create with relations
```typescript
const user = await prisma.user.create({
data: {
email: 'alice@prisma.io',
posts: {
create: [
{ title: 'Post 1' },
{ title: 'Post 2' }
]
},
profile: {
create: { bio: 'Hello!' }
}
}
})
```
### Create or connect
```typescript
const post = await prisma.post.create({
data: {
title: 'New Post',
author: {
connectOrCreate: {
where: { email: 'alice@prisma.io' },
create: { email: 'alice@prisma.io', name: 'Alice' }
}
}
}
})
```
### Connect existing
```typescript
const post = await prisma.post.create({
data: {
title: 'New Post',
author: {
connect: { id: 1 }
}
}
})
// Shorthand for foreign key
const post = await prisma.post.create({
data: {
title: 'New Post',
authorId: 1
}
})
```
## Update Relations
### Update related records
```typescript
const user = await prisma.user.update({
where: { id: 1 },
data: {
posts: {
update: {
where: { id: 1 },
data: { title: 'Updated Title' }
}
}
}
})
```
### Update many related
```typescript
const user = await prisma.user.update({
where: { id: 1 },
data: {
posts: {
updateMany: {
where: { published: false },
data: { published: true }
}
}
}
})
```
### Upsert related
```typescript
const user = await prisma.user.update({
where: { id: 1 },
data: {
profile: {
upsert: {
create: { bio: 'New bio' },
update: { bio: 'Updated bio' }
}
}
}
})
```
### Disconnect
```typescript
// 1-to-1 optional
const user = await prisma.user.update({
where: { id: 1 },
data: {
profile: { disconnect: true }
}
})
// Many-to-many
const post = await prisma.post.update({
where: { id: 1 },
data: {
tags: {
disconnect: [{ id: 1 }, { id: 2 }]
}
}
})
```
### Delete related
```typescript
const user = await prisma.user.update({
where: { id: 1 },
data: {
posts: {
delete: { id: 1 }
}
}
})
// Delete many
const user = await prisma.user.update({
where: { id: 1 },
data: {
posts: {
deleteMany: { published: false }
}
}
})
```
### Set (replace all)
```typescript
// Replace all related records
const post = await prisma.post.update({
where: { id: 1 },
data: {
tags: {
set: [{ id: 1 }, { id: 2 }]
}
}
})
```
## Relation Filters
### some
At least one matches:
```typescript
const users = await prisma.user.findMany({
where: {
posts: { some: { published: true } }
}
})
```
### every
All match:
```typescript
const users = await prisma.user.findMany({
where: {
posts: { every: { published: true } }
}
})
```
### none
None match:
```typescript
const users = await prisma.user.findMany({
where: {
posts: { none: { published: true } }
}
})
```
### is / isNot (1-to-1)
```typescript
const users = await prisma.user.findMany({
where: {
profile: { is: { country: 'USA' } }
}
})
```
## Count Relations
```typescript
const users = await prisma.user.findMany({
select: {
name: true,
_count: {
select: { posts: true, followers: true }
}
}
})
// { name: 'Alice', _count: { posts: 5, followers: 100 } }
```
### Filter counted relations
```typescript
const users = await prisma.user.findMany({
select: {
name: true,
_count: {
select: {
posts: { where: { published: true } }
}
}
}
})
```