use*_*972 4 node.js sequelize.js
当我查询模型(简短版本)时,这是一个错误吗?
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' });
Run Code Online (Sandbox Code Playgroud)
此查询工作正常(注意include包含在include中):
User.findOne({
include: [{
model: Group,
as: 'Groups',
where: {
name: 'Group name',
},
include: [{
model: GroupSection,
as: 'GroupSection',
}]
}]
}).then(function(user) {
// some code
})
Run Code Online (Sandbox Code Playgroud)
但是此查询给出了错误(仅将“ where”参数添加到内部include):
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
})
Run Code Online (Sandbox Code Playgroud)
上面的代码给出错误:
未处理的拒绝SequelizeDatabaseError:缺少表“ Groups”的FROM子句条目
我检查了它产生的SQL代码,可以通过不使用内部where子句来解决此问题,而是将一些原始代码添加到where子句中。我该如何做这样的事情:
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
})
Run Code Online (Sandbox Code Playgroud)
没有内部where生成的代码(工作正常):
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";
Run Code Online (Sandbox Code Playgroud)
用内部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"
FROM (SELECT "User"."id",
"User"."login",
"User"."password",
"User"."createdat",
"User"."updatedat",
"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 "users" AS "User"
INNER JOIN "groupsections" AS "Groups.GroupSection"
ON "groups"."GroupSectionId" = "Groups.GroupSection"."id"
AND "Groups.GroupSection"."name" = 'Section name'
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';
Run Code Online (Sandbox Code Playgroud)
注意真正需要的内容:
我不需要包含没有组的用户或没有节的组等的记录。例如,将组附加到用户后,即找到该用户(并决定将其纳入结果)。这意味着我需要该“ where”子句位于用户模型上(与该对象中的第一个“包含”键处于同一级别),但是它需要检查多个表(我的真实数据库更加复杂) 。
我有类似的错误。而且我没有找到解决问题的答案。但是我让它起作用。我不知道它是否也适用于您,但是我写了我的解决方案。
请尝试添加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
})
Run Code Online (Sandbox Code Playgroud)
为什么这对我有用,应该对您有用?当您where在最后一个子查询中省略时,默认情况下required其值为false。设置时where,默认情况下required值为true。这将我引导至此解决方案。
来自文档作为确认:
[options.include []。where] where子句适用于子模型。请注意,除非您明确设置required,否则这会将急切的负载转换为内部联接。
和
[options.include []。required]如果为true,则转换为内部联接,这意味着仅在具有任何匹配子代的情况下加载父模型。如果设置了include.where,则为true,否则为false。
简而言之,内部联接存在一些问题。并且当您设置where属性时,除非您设置,否则此添加子查询为内部联接required:false。
| 归档时间: |
|
| 查看次数: |
4143 次 |
| 最近记录: |