设置Sequelize关联时出现问题-使用“ include”的查询失败

时间:2019-07-09 13:39:27

标签: node.js sequelize.js

我是Sequelize的新手,它试图测试我在两个模型(用户模型和播客模型)之间建立的n:m关联是否有效。当我尝试运行此查询时,出现某种数据库错误,该错误并非特定于错误所在:

User.findOne({
    where: { id: id },
    include: [{ model: Podcast }]
});

有人知道我在搞砸吗?我怀疑我建立关联的方式有问题,例如我略微错误地引用了表名,但是创建关联的迁移却可行。

这是我的User.js模型文件:

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    name: {
      type: DataTypes.STRING,
      allowNull: false
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
      unique: true
    },
    photo: {
      type: DataTypes.STRING
    }
  });
  User.associate = function(models) {
    // associations can be defined here
    User.belongsToMany(models.Podcast, {
      through: 'user_podcast'
    });
  };
  return User;
};

这是我的Podcast.js文件:

'use strict';
module.exports = (sequelize, DataTypes) => {
  const Podcast = sequelize.define('Podcast', {
    id: {
      type: DataTypes.STRING,
      primaryKey: true,
      allowNull: false
    },
    title: {
      type: DataTypes.STRING,
      allowNull: false
    },
    thumbnail: {
      type: DataTypes.STRING
    },
    website: {
      type: DataTypes.STRING
    }
  });
  Podcast.associate = function(models) {
    // associations can be defined here
    Podcast.belongsToMany(models.User, {
      through: 'user_podcast'
    });
  };
  return Podcast;
};

这是我为连接两个表而进行的迁移:

'use strict';
module.exports = {
  up: function(queryInterface, Sequelize) {
    return queryInterface.createTable('user_podcast', {
      id: {
        allowNull: false,
        autoIncrement: true,
        primaryKey: true,
        type: Sequelize.INTEGER
      },
      userId: {
        type: Sequelize.INTEGER,
        references: {
          model: 'Users',
          key: 'id'
        }
      },
      podcastId: {
        type: Sequelize.STRING,
        references: {
          model: 'Podcasts',
          key: 'id'
        }
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE
      }
    });
  },
  down: function(queryInterface, Sequelize) {
    return queryInterface.dropTable('user_podcast');
  }
};

这是Github上的项目,以供进一步参考: https://github.com/olliebeannn/chatterpod

1 个答案:

答案 0 :(得分:0)

您无需为M:N表创建迁移。现在,您的user_podcast模型出现了问题。如果要在表之间设置M:N关系,则您的主键将是这两个模型的外键之间的组合。如果您仍要为表使用单个id主键,则在belongsToManyhasMany模型上,您将不使用user而是使用podcast新模型user_podcast

据我在第一个查询中看到的,您似乎确实需要一个M:N关系,因此可以像对userpodcast那样定义模型,如下所示:

module.exports = (sequelize, DataTypes) => {
  const UserPodcast = sequelize.define('user_podcast', {
    userId: {
      // field: 'user_id', #Use 'field' attribute is you have to match a different format name on the db
      type: DataTypes.INTEGER
    },
    podcastId: {
      // field: 'podcast_id',
      type: DataTypes.INTEGER
    },
  });
  UserPodcast.associate = function(models) {
    models.User.belongsToMany(models.Podcast, { 
      as: 'podcasts',  //this is very important
      through: { model: UserPodcast }, 
      // foreignKey: 'user_id' 
    });
    models.Podcast.belongsToMany(models.User, { 
      as: 'users',      
      through: { model: UserPodcast }, 
      // foreignKey: 'podcast_id' 
    });
  };
  return UserPodcast;
};

我确实更喜欢在定义连接模型的保存功能上具有belongsToMany关联,并且您必须注意到我在关联上使用了as:属性。这非常重要,因为这将帮助您顺序了解您在查询中指的是哪个关联。

User.findOne({
  where: { id: id },
  include: [{ 
    model: Podcast, 
    as: 'podcasts' //here I use the previous alias
  }]
});