使用关联序列化批量插入

0xo*_*ori 6 bulkinsert associations node.js sequelize.js

我正在尝试批量插入关联,我有这个“歌曲”模型,它与使用迁移 CLI 定义的“流派”和“语言”具有一对多关系。歌曲:

module.exports = (sequelize, DataTypes) => {
    class Song extends Model {
     
        static associate(models) {
            // define association here
            Song.hasMany(models["Language"])
            Song.hasMany(models["Genre"])
        }
    };
    Song.init({
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        name: DataTypes.STRING,
        energy: {type: DataTypes.FLOAT, allowNull: false},
        valence: {type: DataTypes.FLOAT, allowNull: false}
    }, {
        sequelize,
        modelName: 'Song',
        timestamps: true
    });
    return Song;
};
Run Code Online (Sandbox Code Playgroud)

语言:

module.exports = (sequelize, DataTypes) => {
    class Language extends Model {
        static associate(models) {
            // define association here
            models["Language"].belongsTo(models["Song"])
        }
    };
    Language.init({
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        name: DataTypes.STRING
    }, {
        sequelize,
        modelName: 'Language',
        indexes: [{unique: true, fields: ['name']}]
    });
    return Language;
};
Run Code Online (Sandbox Code Playgroud)

类型:

module.exports = (sequelize, DataTypes) => {
    class Genre extends Model {
        /**
         * Helper method for defining associations.
         * This method is not a part of Sequelize lifecycle.
         * The `models/index` file will call this method automatically.
         */
        static associate(models) {
            // define association here
            models["Genre"].belongsTo(models["Song"])
        }
    };
    Genre.init({
        id: {
            type: DataTypes.INTEGER,
            autoIncrement: true,
            primaryKey: true
        },
        name: DataTypes.STRING
    }, {
        sequelize,
        modelName: 'Genre',
        indexes: [{unique: true, fields: ['name']}]
    });
    return Genre;
};
Run Code Online (Sandbox Code Playgroud)

我正在尝试批量插入具有如下语言和流派的歌曲:

Song.bulkCreate(songs, {
    include: [Genre,Language]
}).then(() => {
    const result = {
        status: "ok",
        message: "Upload Successfully!",
    }
    res.json(result);
});
Run Code Online (Sandbox Code Playgroud)

歌曲数组中的每首歌曲的结构如下:

{
    name: "abc",
    genres: [{name: "abc"}],
    languages: [{name: "English"}],
    energy:  1,
    valence: 1
}
Run Code Online (Sandbox Code Playgroud)

我最终得到了完整的歌曲表,但流派和语言是空的我做错了什么?谢谢。

Eli*_*awy 14

为了防止其他人通过搜索到达这里,从5.14 版本开始 Sequelize 添加了使用选项,include option in bulkCreate如下所示:

await Song.bulkCreate(songsRecordsToCreate, {
    include: [Genre,Language]
})
Run Code Online (Sandbox Code Playgroud)

  • 他们仍然没有文档中描述的这个选项(v5 和 v6) (4认同)

Ana*_*oly 4

2023 年 2 月 2 日编辑

由于上面没有人回答,从v5.14.0开始,该include选项现在可以在bulkInsert.


不幸的bulkCreate是不支持include像这样做的选项create。您应该create在事务内的循环中使用。

const transaction = ...
for (const song of songs) {
  await Song.create(song, {
    include: [Genre,Language]
  }, { transaction })
}
await transaction.commit()
Run Code Online (Sandbox Code Playgroud)

或者您可以使用 Promise.all 来避免使用for.