Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Sequelizejs与otherKey之间的关系_Javascript_Node.js_Sequelize.js - Fatal编程技术网

Javascript Sequelizejs与otherKey之间的关系

Javascript Sequelizejs与otherKey之间的关系,javascript,node.js,sequelize.js,Javascript,Node.js,Sequelize.js,我正在创建一个关于歌曲和艺术家的应用程序,以下是数据库模式: 歌曲有很多艺术家,艺术家有很多歌曲,这是一个多对多的关系,所以我定义了一个联接表songaister: 歌手模型: module.exports = function(sequelize, DataTypes) { var SongArtist = sequelize.define('SongArtist', { id: { type: DataTypes.INTEGER, allowNull: f

我正在创建一个关于歌曲和艺术家的应用程序,以下是数据库模式:

歌曲有很多艺术家,艺术家有很多歌曲,这是一个多对多的关系,所以我定义了一个联接表
songaister

歌手模型:

module.exports = function(sequelize, DataTypes) {
  var SongArtist = sequelize.define('SongArtist', {
    id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    songId: {
      type: DataTypes.INTEGER,
      allowNull: false,

    },
    artistId: {
      type: DataTypes.INTEGER,
      allowNull: false,

    }
  }, {
    tableName: 'SongArtist',
  });
  return SongArtist;
};
默认行为是使用
SongArtister
Artisters
主键('id')进行查询,但我想使用歌曲和艺术家对多对多查询中的
neteaseId
列,因此我在下面使用
otherKey

歌曲型号:

module.exports = function(sequelize, DataTypes) {
  var Songs = sequelize.define('Songs', {
    id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    name: {
      type: DataTypes.STRING,
      allowNull: true
    },
    neteaseId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      unque: true
    }
  }, {
    tableName: 'Songs',
    classMethods: {
      associate: (models) => {
        Songs.belongsToMany(models.Artists,{
          through: 'SongArtist',
          foreignKey: 'songId',
          otherKey: 'neteaseId'
        })
      }
    }
  });

  return Songs;
};
艺术家模型:

module.exports = function(sequelize, DataTypes) {
  var Artists = sequelize.define('Artists', {
    id: {
      type: DataTypes.INTEGER,
      allowNull: false,
      primaryKey: true,
      autoIncrement: true
    },
    name: {
      type: DataTypes.STRING,
      allowNull: true
    },
    neteaseId: {
      type: DataTypes.INTEGER,
      allowNull: false,
      unque: true
    }
  }, {
    tableName: 'Artists',
    classMethods: {
      associate: (models) => {
        Artists.belongsToMany(models.Songs,{
          through: 'SongArtist',
          foreignKey: 'artistId',
          otherKey: 'neteaseId'
        })
      }
    }
  });

  return Artists;
};
但当我使用以下代码执行查询时,它会向我抛出错误:

models.Songs.findAll({include: [models.Artists, models.Album]})

> SequelizeDatabaseError: column Artists.SongArtist.neteaseId does not exist
那么如何更改多对多查询中的默认查询列,并应生成以下sql:

LEFT OUTER JOIN ("SongArtist" AS "Artists.SongArtist"
INNER JOIN "Artists" AS "Artists" ON "Artists"."neteaseId" =    "Artists.SongArtist"."artistId") 
ON "Songs"."id" = "Artists.songId"."songId"
而不是

LEFT OUTER JOIN ("SongArtist" AS "Artists.SongArtist"
INNER JOIN "Artists" AS "Artists" ON "Artists"."id" =   "Artists.SongArtist"."artistId") 
ON "Songs"."id" = "Artists.SongArtist"."songId"

您使用的
otherKey
选项不用于选择关联中使用的源模型字段。根据
otherKey

联接表中外键的名称(表示目标模型)或表示另一列类型定义的对象的名称(有关语法,请参阅Sequelize.define)。使用对象时,可以添加name属性来设置列的名称。默认为目标的名称+目标的主键

它在目标模型的联接表中指定外键,因此它是联接表中的一列,而不是源/目标表中的一列。而且,根据Sequelize的源代码,在这种关联中不可能使用主键以外的字段。下面是一行从源模型中选择字段的代码

const sourceKey = this.source.rawAttributes[this.source.primaryKeyAttribute];
其中
this.source
是您的源代码模型,而不是
Song
Artist
。如您所见,它会自动选择此模型的
primaryKeyAttribute
,在这两种情况下都是
id
字段。
github上甚至存在一个与您遇到的相同问题有关的问题,答案是,在这种情况下,只有主键字段是可接受的-

支持
targetKey
sourceKey
,在Sequelize中添加了多对多关系,如中所述

这里引用

有四种情况需要考虑:

我们可能希望使用默认的主节点建立多对多关系 Foo和Bar的键:

Foo.belongsToMany(Bar, { through: 'foo_bar' }); // This creates a junction table `foo_bar` with fields `fooId` and `barId`
Foo.belongsToMany(Bar, { through: 'foo_bar', sourceKey: 'name', targetKey: 'title' }); // This creates a junction table `foo_bar` with fields `fooName` and `barTitle`
对于Foo,我们可能希望使用默认主键>建立多对多关系,但对于Bar,则需要一个不同的字段:

Foo.belongsToMany(Bar, { through: 'foo_bar', targetKey: 'title' }); // This creates a junction table `foo_bar` with fields `fooId` and `barTitle`
我们可能希望使用不同的Foo字段和默认的Bar主键建立多对多关系:

Foo.belongsToMany(Bar, { through: 'foo_bar', sourceKey: 'name' }); // This creates a junction table `foo_bar` with fields `fooName` and `barId`
我们可能希望对Foo和Bar使用不同的字段建立多对多关系:

Foo.belongsToMany(Bar, { through: 'foo_bar' }); // This creates a junction table `foo_bar` with fields `fooId` and `barId`
Foo.belongsToMany(Bar, { through: 'foo_bar', sourceKey: 'name', targetKey: 'title' }); // This creates a junction table `foo_bar` with fields `fooName` and `barTitle`
代码示例如所示。粘贴在这里以供快速参考

const User = this.sequelize.define('User', {
  id: {
    type: DataTypes.UUID,
    allowNull: false,
    primaryKey: true,
    defaultValue: DataTypes.UUIDV4,
    field: 'user_id'
  },
  userSecondId: {
    type: DataTypes.UUID,
    allowNull: false,
    defaultValue: DataTypes.UUIDV4,
    field: 'user_second_id'
  }
}, {
  tableName: 'tbl_user',
  indexes: [
    {
      unique: true,
      fields: ['user_second_id']
    }
  ]
});
const Group = this.sequelize.define('Group', {
  id: {
    type: DataTypes.UUID,
    allowNull: false,
    primaryKey: true,
    defaultValue: DataTypes.UUIDV4,
    field: 'group_id'
  },
  groupSecondId: {
    type: DataTypes.UUID,
    allowNull: false,
    defaultValue: DataTypes.UUIDV4,
    field: 'group_second_id'
  }
}, {
  tableName: 'tbl_group',
  indexes: [
    {
      unique: true,
      fields: ['group_second_id']
    }
  ]
});
User.belongsToMany(Group, {
  through: 'usergroups',
  sourceKey: 'userSecondId'
});
Group.belongsToMany(User, {
  through: 'usergroups',
  sourceKey: 'groupSecondId'
});