You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Sequelize关联查询:如何获取项目关联的负责人及页面列表

完善Sequelize关联查询的解决方案

要实现获取项目关联的负责人名称和页面数组,需要分两步:定义模型间的关联关系,然后在查询中添加关联查询配置。

1. 补充模型间的关联定义

首先需要在模型文件中显式定义关联关系,Sequelize才能识别并执行关联查询。

修改Project.model.ts

在文件末尾添加与Manager和Page的关联,并修正类型定义:

import { DataTypes, Model, CreationOptional, InferCreationAttributes, InferAttributes, BelongsToGetAssociationMixin, HasManyGetAssociationsMixin } from 'sequelize';
import sequelize from '../../loaders/db';
import Manager from '../manager/manager.model';
import Page from '../page/page.model'; // 新增导入Page模型

const tableName = 'project';

// 修正id类型为string(匹配UUID),添加关联属性用于类型提示
export interface ProjectModel extends Model<InferAttributes<ProjectModel>, InferCreationAttributes<ProjectModel>>  {
  id:  CreationOptional<string>;
  name: string;
  managerId: number | null;
  manager?: ManagerModel;
  pages?: PageModel[];
  // 关联方法的类型定义
  getManager: BelongsToGetAssociationMixin<ManagerModel>;
  getPages: HasManyGetAssociationsMixin<PageModel>;
}

const Project = sequelize().define<ProjectModel>(
  tableName,
  {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV4,
    },
    name: {
      type: DataTypes.STRING(100),
      allowNull: false,
    },
    managerId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      references: {
        model: Manager,
        key: 'id',
      },
      field: 'conformance_id',
    },
  },
  {
    timestamps: false,
  }
);

// 定义关联:Project属于一个Manager
Project.belongsTo(Manager, {
  foreignKey: 'managerId',
  as: 'manager', // 别名,查询时用此名称引用
  targetKey: 'id'
});

// 定义关联:Project拥有多个Page
Project.hasMany(Page, {
  foreignKey: 'projectId',
  as: 'pages', // 别名
  sourceKey: 'id'
});

export default Project;

修改Page.model.ts

在文件末尾添加与Project的关联(完善关联闭环):

// ... 原有代码 ...

// 定义关联:Page属于一个Project
Page.belongsTo(Project, {
  foreignKey: 'projectId',
  as: 'project',
  targetKey: 'id'
});

export default Page;

2. 完善getProjectById方法的关联查询

修改Project.service.ts,导入关联模型,并在findOne中添加include配置:

import { Service } from 'typedi';
import Project from './project.model';
import Manager from '../manager/manager.model'; // 新增导入
import Page from '../page/page.model'; // 新增导入

@Service()
export default class ProjectService {
  async getProjectById(id: string) {
    try {
      const project = await Project.findOne({
        where: { id },
        // 添加关联查询配置
        include: [
          {
            model: Manager,
            as: 'manager', // 与模型定义的别名一致
            attributes: ['name'] // 仅获取负责人名称,减少冗余数据
          },
          {
            model: Page,
            as: 'pages', // 与模型定义的别名一致
            attributes: ['id', 'name'] // 按需获取页面字段,可根据需求调整
          }
        ]
      });
      if (!project) {
        throw new Error('Project not found');
      }
      return project;
    } catch (error) {
      throw new Error('Failed to fetch Project by ID');
    }
  }
}

关键说明

  • 关联别名as必须在模型定义和查询中保持一致,否则Sequelize无法识别关联关系。
  • 使用attributes指定返回字段,避免获取冗余数据,提升查询性能。
  • 修正了ProjectModel中id的类型为string,与模型中UUID类型的实际数据匹配,避免类型报错。

内容的提问来源于stack exchange,提问作者Jay Bhajiyawala

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 00:44:58