排除外键属性会​​导致嵌套查询失败

时间:2016-08-08 18:24:29

标签: mysql node.js sequelize.js

在我的所有模型上,我都有一个链接到我的用户模型的外键列创建并更新。例如,当我使用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"
}

所以我所做的只是排除createdByIdupdatedById属性,这很有效,直到我必须加入其他表并包含约束(用于分页,导致生成子查询)查找我最初排除的createdByIdupdatedById列,导致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
});

0 个答案:

没有答案