2017-08-20 268 views
0

我有兩個型號的表,像如何在Sequelize中使用JOIN LEFT?

Project = Sequelize.define('Project',{ 
    name: Sequelize.STRING 
}); 

Task = Sequelize.define('Task',{ 
    name:Sequelize.STRING, 
    status: Sequelize.BOOLEAN, 
    deadline: Sequelize.DATE, 
    from_name: Sequelize.STRING, 
    ProjectId: Sequelize.INTEGER 
}); 

我需要從兩個表中找到的所有記錄。如何在Sequelize中執行此查詢?

SELECT * FROM mydb.Projects 
LEFT JOIN mydb.Tasks ON Projects.id = Tasks.Project_id 

我使用:

exports.list = function (req, res) { 

    Project.hasMany(Task,{ foreignKey: { allowNull: false }, onDelete: 'CASCADE' }); 
    Project.all({ 
    include: [{ 
     model: Task, 
     required:false, 
     where:{ProjectId: Sequelize.col('Project.id')} 
    }] 
    }) 
    .then(function (projects) { 
    res.render('TODOList', {title: 'TODO', projects: projects || [] }); 
    console.log(projects); 
    }) 
    .catch(function (err) { 
    if (err) { 
     res.render('TODOList', {title: 'TODO List'}); 
    } 
    }); 

}; 

,但我得到的記錄只能從項目,如:

Project { 
    dataValues: { 
    id: 5, 
    name: 'pr2', 
    createdAt: 2017-08-20T07:03:09.000Z, 
    updatedAt: 2017-08-20T07:41:47.000Z, 
    Tasks: [Object] 
    } 
} 

我怎樣才能獲得任務(Project.dataValues.Task)記錄?

+0

這就是所謂的:'急切加載',實際上它是用ORM做這件事的最好方式,稍等一下我會給你解答回答 – num8er

+0

「兩張表中的所有記錄」是什麼意思?左連接返回內連接行以及由空值擴展的不匹配左錶行。內部連接返回也滿足條件的左表格行和右表格行的所有組合。請閱讀並在[mcve]上採取行動。 – philipxy

+0

@philipxy,這意味着我需要獲得項目和與之相關的所有記錄。 –

回答

0

所以模型(說:db/models.js):

const 
    Project = Sequelize.define(
    'Project', 
    { 
     name: Sequelize.STRING 
    }), 
    Task = Sequelize.define(
    'Task', 
    { 
     name: Sequelize.STRING, 
     status: Sequelize.BOOLEAN, 
     deadline: Sequelize.DATE, 
     from_name: Sequelize.STRING, 
     ProjectId: Sequelize.INTEGER 
    }); 

// relations must be defined once in model definition part (not like You do in every request 
Project.hasMany(Task, {foreignKey: {allowNull: false}, onDelete: 'CASCADE'}); 
Task.belongsTo(Project); 

module.exports = {Project, Task}; 

,並在您的路由器的處理器(說routes/projects/list.js):

const Sequelize = require('sequelize'); 
const {Project, Task} = require('../../db/models'); 

module.exports.list = (req, res) => { 
    const query = { 
    include: [{ 
     model: Task, 
     as: 'tasks', 
     required: false 
    }] 
    }; 
    Project 
    .all(query) 
    .then(function (projects) { 
     // it's not recommended, but You insist to get read of model instances and have normal array of objects 
     projects = projects ? projects.map(project => project.toJSON()) : []; 

     res.render(
     'TODOList', 
     { 
      title: 'TODO', 
      projects 
     }); 
     console.log(projects); 
    }) 
    .catch(function (err) { 
     console.error(err); 
     res.render('TODOList', {title: 'TODO List'}); 
    }); 
}; 

但由於sequelize模型實例sequelize回報陣列 - 這是正常有dataValues不用擔心只是照常使用:

for(let project of projects) { 
    console.log(project.tasks[0].name); 
} 
+1

非常感謝,它對我有用!我意識到我的錯誤 –

+0

@ВоваЖуравлёв幸福是有益的 – num8er