Nest.js/Prisma/PostgreSQL中如何实现嵌套API响应的数据结构?
解决方案
1. 修正Prisma数据模型
你现有模型存在命名混淆、缺少层级的问题,需重新设计来匹配目标嵌套结构:
// 季模型:存储季的基础信息 model Season { id Int @id @default(autoincrement()) name String @db.VarChar(40) // 对应响应中的 "Season 1" "Season 2" episodes Episode[] // 关联该季下的所有剧集 } // 剧集模型:对应响应中的seria model Episode { id Int @id @default(autoincrement()) title String @db.VarChar(100) // 对应 "text 1 1" 这类标题 url String @db.VarChar(200) // 对应剧集链接 date String @db.VarChar(20) // 对应日期字符串,若需存储时间可改用 DateTime 类型 seasonId Int // 关联季的外键 season Season @relation(fields: [seasonId], references: [id], onDelete: Cascade) }
2. 执行Prisma迁移
修改模型后,运行以下命令更新数据库:
# 生成迁移文件并应用到数据库 npx prisma migrate dev --name init-seasons-episodes # 更新Prisma客户端,确保代码能调用新模型 npx prisma generate
3. 查询并转换为目标JSON格式
数据库存储的是标准化关系数据,动态键名(SeasonX、seriaX)属于业务层格式需求,需在Nest.js服务中做转换:
// 在seasons.service.ts中实现查询方法 async getSeasons(): Promise<any[]> { // 查询所有季并关联对应的剧集 const seasons = await this.prisma.season.findMany({ include: { episodes: true }, }); // 转换为目标嵌套格式 return seasons.map((season, seasonIndex) => { // 生成Season1、Season2这类动态键 const seasonKey = `Season${seasonIndex + 1}`; // 将剧集数组转为seria1、seria2为键的对象 const seriesObj = season.episodes.reduce((acc, episode, epiIndex) => { const seriaKey = `seria${epiIndex + 1}`; acc[seriaKey] = { title: episode.title, url: episode.url, date: episode.date, }; return acc; }, {} as Record<string, { title: string; url: string; date: string }>); return { [seasonKey]: { name: season.name, series: seriesObj, }, }; }); }
补充说明
- 动态键名属于前端/业务展示需求,不需要在数据库模型中实现,通过代码转换即可完成。
- 若日期字段需存储实际时间,可将Episode模型中的
date类型改为DateTime,查询时再转为字符串格式。
内容的提问来源于stack exchange,提问作者Romio
相关产品推荐
相关产品推荐

