【问题标题】:Converting SQL query to Sequelize ORM returns unwanted result将 SQL 查询转换为 Sequelize ORM 会返回不需要的结果
【发布时间】:2019-09-14 16:39:16
【问题描述】:

我是 Sequelize 和 ORM 概念的初学者。我已成功将查询转换为 Sequelize findAll() 函数,但它返回不需要的结果。 PostgreSQL 查询可以正常工作并且返回结果非常好。

有关系的表:

  1. writers(writerId PK, writerName)
  2. 帖子(postId PK、postTitle、postDescription)
  3. skillmatrix(skillmatrixId PK, writerId FK, postId FK, writerSkill)

我的查询:

SELECT writers."writerName", posts."postTitle", posts."postDescription", 
skillmatrix.* 
FROM writers
INNER JOIN skillmatrix
      ON writers."writerId" = skillmatrix."writerId"
INNER JOIN posts
      ON skillmatrix."postId" = posts."postId"
      ORDER BY writers."writerId", posts."postId"

SQL 查询的输出:

Sequelize 中的关系:

db.skillmatrix.hasMany(db.posts,{foreignKey: 'postId'});
db.skillmatrix.hasMany(db.writers,{foreignKey: 'writerId'});

Sequelize 中的 findAll() 方法:

exports.findAll = (req, res, next) => {
SkillMatrix.findAll({
    include: [
        {
            model: Writer,
            required: true
        },
        {
            model: Post, 
            required: true
        }
    ],
    order:[
        ['"writerId"', 'ASC'],
        ['"postId"', 'ASC']
    ]
})
.then(skillmatrix => {
    res.status(200).json(skillmatrix);
})
.catch(err => {
    console.log(err);
    res.status(500).json({msg: "error", details: err});
});
};

Sequelize 的 JSON 输出:

{
    "skillMatrixId": 1,
    "writerId": 1,
    "postId": 1,
    "writerSkill": "None",
    "writers": [
        {
            "writerId": 1,
            "writerName": "Writer1"
        }
    ],
    "posts": [
        {
            "postId": 1,
            "postTitle": "Post1"
            "postDescription": "This is Post1"
        }
    ]
},
{
    "skillMatrixId": 2,
    "writerId": 1,
    "postId": 2,
    "writerSkill": "SEO",
    "writers": [
        {
            "writerId": 2,
            "writerName": "Writer2"  //This is unexpected
        }
    ],
    "posts": [
        {
            "postId": 2,
            "postTitle": "Post2",
            "postDescription": "This is Post2"
        }
    ]
},
{
    "skillMatrixId": 3
    "writerId": 1,
    "postId": 3,
    "writerSkill": "Proofread"
    "writers": [
        {
            "writerId": 3,  //Unexpected
            "writerName": "Writer3" 
        }
    ],
    "posts": [
        {
            "postId": 3,
            "postTitle": "Post3",
            "postDescription": "This is Post3"
        }
    ]
}...

请告诉我,我做错了什么。还建议我一些很好的资源,我可以在其中深入学习。谢谢你。

编辑:

Sequelize 日志查询:

SELECT "skillmatrix"."skillMatrixId", 
"skillmatrix"."writerId", "skillmatrix"."postId",
"skillmatrix"."writerSkill", 
"writers"."writerId" AS "writers"."writerId",  
"writers"."writerName" AS "writers"."writerName", 
"posts"."postId" AS "posts"."postId", 
"posts"."postTitle" AS "posts"."postTitle", 
"posts"."postDescription" AS "posts"."postDescription", 
"posts"."writerId" AS "posts"."writerId"
FROM "skillmatrix" AS "skillmatrix" 
INNER JOIN "writers" AS "writers" ON "skillmatrix"."skillMatrixId" = 
"writers"."writerId" 
INNER JOIN "posts" AS "posts" ON "skillmatrix"."skillMatrixId" = 
"posts"."postId" 
ORDER BY "skillmatrix"."writerId" ASC, "skillmatrix"."postId" ASC

【问题讨论】:

  • order by 是在整个 from 之后完成的,因此您的缩进没有反映含义。 PS请use text, not images/links, for text--including tables & ERDs.转述或引用其他文本。仅将图像用于无法表达为文本或增强文本的内容。无法搜索或剪切和粘贴图像。在图像中包含图例/键和说明。让您的帖子自成一体。
  • 注明。谢谢。我会记住这一点的。

标签: sql node.js postgresql join sequelize.js


【解决方案1】:

首先,您应该检查 sequelize 日志 - 您的 findAll 生成了什么查询?我猜它加入了错误的领域。

Sequelize 为多对多关系提供了一些选项。你可以试试:

db.posts.belongsToMany  (db.writers, {as : 'p2w', through: db.skillMatrix, foreignKey: 'postId'   });
db.writers.belongsToMany(db.posts,   {as : 'w2p', through: db.skillMatrix, foreignKey: 'writerId' });

db.posts.findAll({
  include: { 
     model: db.writers, 
     as: 'p2w',
     required: true
   }
});

我正在近似语法 - 请在文档中查看:belongsToMany

编辑 - 您现有的关联可以修复如下:

db.skillmatrix.hasMany(db.writers,{sourceKey: 'writerId', foreignKey: 'writerId'});

但是,请记住未来任务的 M:M 选项 :)

【讨论】:

  • 你好@KenOn10。感谢您的回答,但是我有什么办法可以在不关联帖子和作者的情况下做到这一点?
  • 我添加了由 sequelize log 生成的 findAll 查询。请再次检查问题。
  • 如果您保持关联不变,您可能会遇到更多问题...也就是说,生成的 SQL 清楚地显示了问题:INNER JOIN "writers" ON "skillmatrix"."skillMatrixId" = "writers"."writerId" 但您需要改用 Skillmatrix.writerId。试试改成db.skillmatrix.hasMany(db.writers,{sourceKey: 'writerId', foreignKey: 'writerId'});
  • 它就像魅力一样。请更新您的答案,以便我接受。感谢您的宝贵时间。
【解决方案2】:

从以下位置更新 Sequelize 关系:

db.skillmatrix.hasMany(db.posts,{foreignKey: 'postId'});
db.skillmatrix.hasMany(db.writers,{foreignKey: 'writerId'});

到:

db.skillmatrix.hasMany(db.posts,{sourceKey: 'postId' , foreignKey: 'postId'});
db.skillmatrix.hasMany(db.writers,{sourceKey: 'writerId' ,foreignKey: 'writerId'});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 2019-12-10
    • 2020-09-12
    • 1970-01-01
    相关资源
    最近更新 更多