在我的所有模型上,我都有一个链接到我的用户模型的外键列创建并更新。例如,当我使用findAll()查询我的数据库时,我总是包含它们以便用我的结果返回用户的用户名和其他详细信息 - 我也排除了结果的外键列,这没有意义返回由对象创建的,包括ID和createdById节点,因为它只是重复的数据
"createdById": "21499bb6-4476-11e6-beb8-9e71128cae77",
"createdBy": {
"id": "21499bb6-4476-11e6-beb8-9e71128cae77",
"username": "mo.gusbi"
},
"updatedById": "21499bb6-4476-11e6-beb8-9e71128cae77",
"updatedBy": {
"id": "21499bb6-4476-11e6-beb8-9e71128cae77",
"username": "mo.gusbi"
}
所以我所做的只是排除createdById
和updatedById
属性,这很有效,直到我必须加入其他表并包含约束(用于分页,导致生成子查询)查找我最初排除的createdById
和updatedById
列,导致SQL错误
SequelizeDatabaseError: SQLITE_ERROR: no such column: Category.createdById
来自生成的查询
SELECT `Category`.*, `children`.`id` AS `children.id`,
`children`.`name` AS `children.name`,
`createdBy`.`id` AS `createdBy.id`,
`createdBy`.`username` AS `createdBy.username`,
`updatedBy`.`id` AS `updatedBy.id`,
`updatedBy`.`username` AS `updatedBy.username`,
`deletedBy`.`id` AS `deletedBy.id`,
`deletedBy`.`username` AS `deletedBy.username`
FROM (
SELECT `Category`.`id`,
`Category`.`name`,
`Category`.`parentId`
FROM `Categories` AS `Category`
WHERE (`Category`.`deletedAt` IS NULL
AND `Category`.`parentId` = NULL)
LIMIT 0, 10
) AS `Category`
LEFT OUTER JOIN `Categories` AS `children`
ON `Category`.`id` = `children`.`parentId`
AND `children`.`deletedAt` IS NULL
LEFT OUTER JOIN `Users` AS `createdBy`
ON `Category`.`createdById` = `createdBy`.`id`
AND `createdBy`.`deletedAt` IS NULL
LEFT OUTER JOIN `Users` AS `updatedBy`
ON `Category`.`updatedById` = `updatedBy`.`id`
AND `updatedBy`.`deletedAt` IS NULL
LEFT OUTER JOIN `Users` AS `deletedBy`
ON `Category`.`deletedById` = `deletedBy`.`id`
AND `deletedBy`.`deletedAt` IS NULL
;
模型
User = sequelize.define('User', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true
},
username: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
validate: {
notEmpty: true,
is: regex.username
}
}
}, {
paranoid: true,
classMethods: {
associate: (models) => {
User.belongsTo(models.User, {
foreignKey: 'createdById',
as: 'createdBy'
});
User.belongsTo(models.User, {
foreignKey: 'updatedById',
as: 'updatedBy'
});
User.belongsTo(models.User, {
foreignKey: 'deletedById',
as: 'deletedBy'
});
}
}
});
Category = sequelize.define('Category', {
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV1,
primaryKey: true
},
name: {
type: DataTypes.STRING,
allowNull: false,
validate: {
notEmpty: true
}
}
}, {
indexes: [{
unique: true,
fields: ['name', 'parentId']
}],
paranoid: true,
classMethods: {
associate: (models: any) => {
Category.belongsTo(models.User, {
foreignKey: 'createdById',
as: 'createdBy'
});
Category.belongsTo(models.User, {
foreignKey: 'updatedById',
as: 'updatedBy'
});
Category.belongsTo(models.User, {
foreignKey: 'deletedById',
as: 'deletedBy'
});
Category.belongsTo(models.Category, {
foreignKey: 'parentId',
as: 'parent'
});
Category.hasMany(models.Category, {
foreignKey: 'parentId',
as: 'children'
});
}
}
});
查询
Category
.findAll({
attributes: [
'id',
'name',
'parentId'
],
where: {
parentId: req.query.parentId
},
include: [
{
model: Category,
as: 'children',
attributes: [
'id',
'name'
]
},
{
model: User,
as: 'createdBy',
attributes: [
'id',
'username'
]
},
{
model: User,
as: 'updatedBy',
attributes: [
'id',
'username'
]
},
{
model: User,
as: 'deletedBy',
attributes: [
'id',
'username'
]
}
],
offset: 0,
limit: 10
});