Node.js的sequelize关联包括

时间:2015-05-15 16:28:52

标签: node.js sequelize.js

当我查询模型(简短版本)时,这是一个错误:

return

此查询工作正常(注意包括内部包含):

var User = db.define('User', {
  login: Sequelize.STRING(16),
  password: Sequelize.STRING,
});

var Group = db.define('Group', {
  name: Sequelize.STRING,
});

var GroupSection = db.define('GroupSection', {
  name: Sequelize.STRING,
});

Group.belongsTo(GroupSection, { as: 'GroupSection',
  foreignKey: 'GroupSectionId' });
GroupSection.hasMany(Group, { as: 'Groups', foreignKey: 'GroupSectionId' });

Group.belongsTo(Group, { as: 'ParentGroup', foreignKey: 'ParentGroupId' });
Group.hasMany(Group, { as: 'ChildGroups', foreignKey: 'ParentGroupId' });

User.belongsToMany(Group, { as: 'Groups', through: 'UsersToGroups' });
Group.belongsToMany(User, { as: 'Users', through: 'UsersToGroups' });

但是这个查询给出了错误(只有“where”参数添加到内部包含):

User.findOne({
    include: [{
      model: Group,
      as: 'Groups',
      where: {
        name: 'Group name',
      },
      include: [{
        model: GroupSection,
        as: 'GroupSection',
      }]
    }]
  }).then(function(user) {
    // some code
  })

上面的代码给出错误:
未处理的拒绝SequelizeDatabaseError:表“Groups”缺少FROM子句条目

我检查了它生成的SQL代码,我可以通过不使用inner where子句来解决这个问题,但是在where子句中添加了一些原始代码。我怎么能这样做:

User.findOne({
    include: [{
      model: Group,
      as: 'Groups',
      where: {
        name: 'Group name',
      },
      include: [{
        model: GroupSection,
        as: 'GroupSection',
        where: {
          name: 'Some section name',
        },
      }]
    }]
  }).then(function(user) {
    // some code
  })

ADDED(代码被一些在线服务美化):

生成的代码没有内部(工作正常):

User.findOne({
  include: [{
    model: Group,
    as: 'Groups',
    where: {
      name: 'Admin',
      $somethin_i_need$: 'raw sql goes here',
    },
    include: [{
      model: GroupSection,
      as: 'GroupSection',
    }]
  }]
}).then(function(user) {
  // some code
})

代码生成WITH inner where(生成错误的sql):

SELECT "User".*,
       "groups"."id"                      AS "Groups.id",
       "groups"."name"                    AS "Groups.name",
       "groups"."createdat"               AS "Groups.createdAt",
       "groups"."updatedat"               AS "Groups.updatedAt",
       "groups"."groupsectionid"          AS "Groups.GroupSectionId",
       "groups"."parentgroupid"           AS "Groups.ParentGroupId",
       "Groups.UsersToGroups"."createdat" AS "Groups.UsersToGroups.createdAt",
       "Groups.UsersToGroups"."updatedat" AS "Groups.UsersToGroups.updatedAt",
       "Groups.UsersToGroups"."groupid"   AS "Groups.UsersToGroups.GroupId",
       "Groups.UsersToGroups"."userid"    AS "Groups.UsersToGroups.UserId",
       "Groups.GroupSection"."id"         AS "Groups.GroupSection.id",
       "Groups.GroupSection"."name"       AS "Groups.GroupSection.name",
       "Groups.GroupSection"."createdat"  AS "Groups.GroupSection.createdAt", 
       "Groups.GroupSection"."updatedat"  AS "Groups.GroupSection.updatedAt"
FROM   (SELECT "User"."id",
               "User"."login",
               "User"."password",
               "User"."createdat",
               "User"."updatedat"
        FROM   "users" AS "User"
        WHERE  (SELECT "userstogroups"."groupid"
                FROM   "userstogroups" AS "UsersToGroups"
                       INNER JOIN "groups" AS "Group"
                               ON "userstogroups"."groupid" = "Group"."id"
                WHERE  ( "User"."id" = "userstogroups"."userid" )
                LIMIT  1) IS NOT NULL
        LIMIT  1) AS "User"
       INNER JOIN ("userstogroups" AS "Groups.UsersToGroups"
                   INNER JOIN "groups" AS "Groups"
                           ON "groups"."id" = "Groups.UsersToGroups"."groupid")
               ON "User"."id" = "Groups.UsersToGroups"."userid"
                  AND "groups"."name" = 'Group name'
       LEFT OUTER JOIN "groupsections" AS "Groups.GroupSection"
                    ON "groups"."groupsectionid" = "Groups.GroupSection"."id";

请注意真正需要的内容

我不需要具有没有分组的用户或没有分段的组的记录等等。例如。在找到该用户之后发生了对用户的组附件(并且决定它将进入结果)。这意味着我需要将这个“where”子句放在用户模型上(与对象中第一个“包含”键处于同一级别),但它需要检查几个表(我的真实数据库更复杂)

1 个答案:

答案 0 :(得分:5)

我有类似的错误。 我没有找到任何问题的答案。 但是我让它发挥作用。我不知道它是否也适合你,但我写了我的解决方案。

请尝试添加最后一个包含的required:false媒体资源:

User.findOne({
    include: [{
      model: Group,
      as: 'Groups',
      where: {
        name: 'Group name',
      },
      include: [{
        model: GroupSection,
        as: 'GroupSection',
        required: false,
        where: {
          name: 'Some section name',
        },
      }]
    }]
  }).then(function(user) {
    // some code
  })

为什么这对我有用,应该适合你? 如果在最后一个子查询中省略where,则默认情况下required的值为false。设置where后,默认情况下required的值为true。这引导我找到这个解决方案。

来自docs作为确认:

  

[options.include [] .where] Where子句适用于孩子   楷模。请注意,这会将预先加载转换为内部联接,   除非你明确设置required:false

  

[options.include [] .requiree]如果为true,则转换为内部   join,这意味着只有父模型才会加载   任何匹配的孩子。如果include.where设置为true,否则为false。

简而言之,内连接存在一些问题。当你设置where属性时,这会将子查询添加为内连接,除非你设置required:false