sequelize v6 的多对对关系,报错Unknown column 'tagsBookmark->bookmarkTag.bookmarkId' in 'field list'?

前端小白,不太懂数据库,业余时间在用 nextjs 和 sequelize 写个小项目,其他 MySQL 问题也跌跌撞撞过来了,但是后面遇到了连表查询、多表关联的问题(belongsToMany),不知问题出在哪里,请大佬帮忙解答,非常感谢!

问题描述: 书签和tag之间属于多对多关系,目前想实现查询某个tag下面对应哪些书签。
报错信息:

"Unknown column 'tagsBookmark->bookmarkTag.bookmarkId' in 'field list'",
    sql: 'SELECT `bookmark`.`id`, `bookmark`.`title`, `bookmark`.`url`, `bookmark`.`image`, `bookmark`.`description`, `bookmark`.`tagsArr`, `bookmark`.`is_favorite`, `tagsBookmark`.`id` AS `tagsBookmark.id`, `tagsBookmark`.`name` AS `tagsBookmark.name`, `tagsBookmark->bookmarkTag`.`id` AS `tagsBookmark.bookmarkTag.id`, `tagsBookmark->bookmarkTag`.`bkId` AS `tagsBookmark.bookmarkTag.bkId`, `tagsBookmark->bookmarkTag`.`tagId` AS `tagsBookmark.bookmarkTag.tagId`, `tagsBookmark->bookmarkTag`.`bookmarkId` AS `tagsBookmark.bookmarkTag.bookmarkId` FROM `bookmark` AS `bookmark` LEFT OUTER JOIN ( `bookmarkTag` AS `tagsBookmark->bookmarkTag` INNER JOIN `tags` AS `tagsBookmark` ON `tagsBookmark`.`id` = `tagsBookmark->bookmarkTag`.`tagId`) ON `bookmark`.`id` = `tagsBookmark->bookmarkTag`.`bookmarkId`;'

image.png

model/bookmark.js


module.exports = (sequelize, DataTypes) => {
  let bookmark = sequelize.define('bookmark', {
    id: {
      type: DataTypes.STRING,
      primaryKey: true,
      autoIncrement: true,
    },
    title: {
      type: DataTypes.STRING, // varchar(255)
      allowNull: false,
      unique: false,
    },
    url: {
      type: DataTypes.STRING, // varchar(255)
      allowNull: false,
      unique: false,
    },
    image: {
      type: DataTypes.STRING, // varchar(255)
      allowNull: true,
      unique: false,
    },
    description: {
      type: DataTypes.STRING, // varchar(255)
      allowNull: true,
      unique: false,
    },
    tagsArr: {
      type: DataTypes.STRING, // varchar(255)
      allowNull: true,
      unique: false,
    },
    is_favorite: {
      type: DataTypes.BOOLEAN, // varchar(255)
      allowNull: true,
      unique: false,
    },
  }, {
    freezeTableName: true, 
    timestamps: false, 
    tableName: 'bookmark',
  });
  bookmark.associate = (models) => {
    models.bookmark.belongsToMany(models.tags,
      {
        as: 'tagsBookmark',
        through: 'bookmarkTag',
      },
    );
  };
  return bookmark;
};

model/tags.js

module.exports = (sequelize, DataTypes) => {
  let tags = sequelize.define('tags', {
    id: {
      type: DataTypes.STRING,
      primaryKey: true,
      autoIncrement: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: false,
    },
  }, {
    freezeTableName: true,
    tableName: 'tags',
    timestamps: false,
  });

  tags.associate = (models) => {
    models.tags.belongsToMany(models.bookmark,
      {
        as: 'tagsBookmark',
        through: 'bookmarkTag',
      },
    );
  };
  return tags;
};

model/bookmarkTag.js

module.exports = (sequelize, DataTypes) => {
  let bookmarkTag = sequelize.define('bookmarkTag', {
    id: {
      type: DataTypes.STRING,
      primaryKey: true,
      autoIncrement: true,
    },
    bkId: {
      type: DataTypes.STRING,
      allowNull: false,
      references: {
        model: sequelize.models.bookmark,
        key: 'id',
      },
    },
    tagId: {
      type: DataTypes.STRING,
      allowNull: false,
      references: {
        model: sequelize.models.tags,
        key: 'id',
      },
    },
  }, {
    freezeTableName: true, 
    tableName: 'bookmarkTag',
    timestamps: false,
  });
  return bookmarkTag;
};

api/tags.js

 const tmp = await models.bookmark.findAll({
          include: {
            model: models.tags,
            as: 'tagsBookmark',
          },
          attributes: ['id'],
        });

问题点:
1、不知道自己的表关联写法有么有问题,不写 as 的话,会报错,写了 as ,但是实际上打算用的关联表是 “bookmarkTag.js”,不明白报错信息为什么会是最上面截图那个。
2、不是非常确定表关联关系是否写得有问题?还烦请后端大佬指出。比如 belongsToMany、associate语法的使用。我用的是 sequelize v6 版本。
再次感谢,困扰了好久了,网上搜索过,但是由于版本变化写写法不一,不知道具体该怎么解决

阅读 2.3k
1 个回答

bookmarkTag.js添加外键:

bookmarkTag.belongsTo(models.bookmark, {
  foreignKey: 'bkId',
  as: 'bookmark'
});

bookmarkTag.belongsTo(models.tags, {
  foreignKey: 'tagId',
  as: 'tag'
});

api/tags.js:

const tmp = await models.bookmark.findAll({
  include: {
    model: models.tags,
    as: 'tagsBookmark',
    through: { attributes: [] }, 
  },
  attributes: ['id'],
});
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题