如何在Sequelize中通过主表p_id关联查询其余三张表的对应数据
Sequelize多表关联查询实现方案
一、先修复现有代码的核心错误
你当前的代码存在几个语法和关联逻辑问题,会导致关联不生效:
- Sequelize.define的参数格式错误:三个参数分别为「模型名」「字段配置对象」「全局配置对象」,你当前把associate、tableName拆成了多个独立参数,配置无法被识别
- 关联关系写反:graph_data属于patient_data,你写成了
graph_data.hasMany(patient_data),应该为graph_data.belongsTo(patient_data) - 字段配置拼写错误:外键关联配置
refereces拼写错误,正确为references,且关联的目标字段应该是patient_data的p_id不是p_name - 跨表关联逻辑错误:vital_data的外键是master_id,关联的是master_session表,需要配置嵌套关联,不能直接关联patient_data
二、修正后的模型代码
表1:patient_data.js
module.exports = function(sequelize, DataTypes) { const patient_data = sequelize.define('patient_data', { sl_no: { type: DataTypes.INTEGER(11), autoIncrement: true, allowNull: false, primaryKey: true, }, patient_name: { type: DataTypes.STRING(35), allowNull: false }, p_id: { type: DataTypes.STRING(100), allowNull: false, unique: true } }, { sequelize, tableName: 'patient_data', associate: function(models){ patient_data.hasMany(models.master_session, { foreignKey: 'p_id' }); patient_data.hasMany(models.graph_data, { foreignKey: 'pid' }); // 表4和表3结构一致,假设模型名为graph_data_extra patient_data.hasMany(models.graph_data_extra, { foreignKey: 'pid' }); }, }); return patient_data; };
表2:master_session.js
module.exports = function(sequelize, DataTypes) { const master_session = sequelize.define('master_session', { master_id: { type: DataTypes.INTEGER(11), autoIncrement: true, allowNull: false, primaryKey: true, }, p_id: { type: DataTypes.STRING(100), allowNull: false, references: { model: 'patient_data', key: 'p_id' } }, session_name: { type: DataTypes.STRING(35), allowNull: true } }, { sequelize, tableName: 'master_session', associate: function(models){ master_session.belongsTo(models.patient_data, { foreignKey: 'p_id' }); master_session.hasMany(models.vital_data, { foreignKey: 'master_id' }); }, }); return master_session; };
表3:graph_data.js(表4直接复制此代码,修改模型名和tableName即可)
module.exports = function(sequelize, DataTypes) { const graph_data = sequelize.define('graph_data', { sl_no: { type: DataTypes.INTEGER(11), autoIncrement: true, allowNull: false, primaryKey: true }, document: { type: DataTypes.STRING(2000), allowNull: true }, pid: { type: DataTypes.STRING(200), allowNull: true, references: { model: 'patient_data', key: 'p_id' } }, session: { type: DataTypes.STRING(200), allowNull: true } }, { sequelize, tableName: 'graph_data', associate: function(models){ graph_data.belongsTo(models.patient_data, { foreignKey: 'pid' }); }, }); return graph_data; };
三、模型关联初始化
你需要在sequelize实例的初始化文件中,统一加载所有模型并触发关联注册,示例代码如下:
const Sequelize = require('sequelize'); const sequelize = new Sequelize('数据库名', '用户名', '密码', { host: 'localhost', dialect: 'mysql' }); // 加载所有模型 const models = { patient_data: require('./patient_data')(sequelize, Sequelize.DataTypes), master_session: require('./master_session')(sequelize, Sequelize.DataTypes), graph_data: require('./graph_data')(sequelize, Sequelize.DataTypes), graph_data_extra: require('./graph_data_extra')(sequelize, Sequelize.DataTypes), vital_data: require('./vital_data')(sequelize, Sequelize.DataTypes) }; // 执行关联注册 Object.keys(models).forEach(modelName => { if (models[modelName].associate) { models[modelName].associate(models); } }); module.exports = { sequelize, models };
四、Express接口实现
在对应的Controller层编写查询逻辑,接收req.body.pid参数即可一次性查询所有关联表数据:
const { models } = require('./sequelize初始化文件路径'); // 接口处理函数 async function getPatientAllData(req, res) { try { const { pid } = req.body; if (!pid) return res.status(400).json({ msg: '缺少pid参数' }); const result = await models.patient_data.findOne({ where: { p_id: pid }, // 加载所有关联表 include: [ models.master_session, models.graph_data, models.graph_data_extra, // 嵌套加载master_session关联的vital_data { model: models.master_session, include: [models.vital_data] } ] }); return res.status(200).json({ data: result }); } catch (err) { console.error(err); return res.status(500).json({ msg: '查询失败' }); } }
内容的提问来源于stack exchange,提问作者fungusblacky
相关产品推荐
相关产品推荐

