加入不适用于sequelize关联belongsToMany

时间:2019-10-05 08:59:12

标签: mysql node.js join sequelize.js

我正在测试带有sequelize的所有关联,但是遇到一个问题,要使用belongsToMany获得很多对很多的联接。

https://github.com/lhferrh/Sequelize-Playground.git

当我执行findAll时,我得到联接结果的所有null

我一直在检查几种组合,但问题是sequelize生成的SQL直接在MySQL上运行,这让我感到非常困惑。

这是提供的sql:

SELECT `user`.`userId`, `user`.`name`, `user`.`createdAt`, `user`.`updatedAt`, `cars`.`carId` AS `cars.carId`, `cars`.`make` AS `cars.make`, `cars`.`createdAt` AS `cars.createdAt`, `cars`.`updatedAt` AS `cars.updatedAt`, `cars->favorites`.`favoritesId` AS `cars.favorites.favoritesId`, `cars->favorites`.`date` AS `cars.favorites.date`, `cars->favorites`.`createdAt` AS `cars.favorites.createdAt`, `cars->favorites`.`updatedAt` AS `cars.favorites.updatedAt`, `cars->favorites`.`userId` AS `cars.favorites.userId`, `cars->favorites`.`carId` AS `cars.favorites.carId` FROM `users` AS `user` LEFT OUTER JOIN ( `favorites` AS `cars->favorites` INNER JOIN `cars` AS `cars` ON `cars`.`carId` = `cars->favorites`.`carId`) ON `user`.`userId` = `cars->favorites`.`userId`;

这是我正在运行的代码:

const Users = sequelize.define('user', {
    userId: {
        type: Sequelize.INTEGER,
        allowNull: false,
        primaryKey: true,
        autoIncrement: true
      },
      name: {
          type: Sequelize.STRING,
      }, 

    } 
);

const Favorites = sequelize.define('favorites', {
    favoritesId: {
      type: Sequelize.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },

    date: {
      type: Sequelize.DATE,
    }
  }
);

  const Cars = sequelize.define('cars', {
    carId: {
        type: Sequelize.INTEGER,
        primaryKey: true,
        autoIncrement: true
      },
      make: Sequelize.STRING
  })

  Users.belongsToMany(Cars, {
    through: 'favorites',
    sourceKey: 'userId',
    foreignKey: 'userId'
  });
  Cars.belongsToMany(Users, {
    through: 'favorites',
    sourceKey: 'carId',
    foreignKey: 'carId'
  });


const intiDataBase = async () => {
    await sequelize.sync({force: true});
}

const run = async () => {
    const max = 3;
    await intiDataBase();

    await Promise.all( DATA.users.map( async elem=> 
         Users.create({...elem})
    ))

    await Promise.all( DATA.cars.map( async elem => 
        Cars.create({...elem})
   ))

   for( let i = 0 ; i < 5 ; i++ ){
       Favorites.create({
           userId: getRandomInt(1 , max),
           carId: getRandomInt(0, max)
       })
   }


   const car = await Users.findAll({
       include: [{
        model: Cars,
        through: {
            attributes: ['userId', 'carId'],

          }
        //attributes: ['make'],
        }],
        raw: true
   });

   const favorites = await Favorites.findAll({
        where:{
            userId:2
        },
        raw: true
    });

   console.log(car);
   console.log(favorites);

} 

run();

这是我得到的结果

    name: 'Johan',
    createdAt: 2019-10-05T08:57:57.000Z,
    updatedAt: 2019-10-05T08:57:57.000Z,
    'cars.carId': null,
    'cars.make': null,
    'cars.createdAt': null,
    'cars.updatedAt': null,
    'cars.favorites.favoritesId': null,
    'cars.favorites.date': null,
    'cars.favorites.createdAt': null,
    'cars.favorites.updatedAt': null,
    'cars.favorites.userId': null,
    'cars.favorites.carId': null } ], ...

这可能是一个命名问题,但是SQL直接起作用的事实确实令人困惑。

我希望你们中的任何人都能看到错误。

顺便说一句,我还想知道通过创建两个与中间表的1:m关联来手动创建多对多关系的缺点是什么?

1 个答案:

答案 0 :(得分:0)

我发现了我的错误。将收藏夹插入数据库时​​,缺少等待。因此,联接在查询中给出错误的结果,并在数据库中直接给出正确的结果。

for( let i = 0 ; i < 5 ; i++ ){
       await Favorites.create({
           userId: getRandomInt(1 , max),
           carId: getRandomInt(0, max)
       })
   }

正如我期望的那样,这是一个愚蠢的错误。

无论如何,我还是对自己使用belongToMany还是自己创建多对多关系感到犹豫,并且总是使用两个步骤。