Sequelize hasMany()关联中的批量插入

时间:2019-12-16 17:03:04

标签: model sequelize.js associations

首先让我解释一下我想做什么。我有两个定义良好的模型UserProduct。在定义与hasMany()belongsTo()的关联时,我使用由sequelize创建的方法来创建产品。

user.hasMany(Product) Product.belongsTo(User)

并且我使用这种方法从product创建了user

User.findOne({where:{id:SomeID}}).then((userObj)=>{
 userObj.createProduct(productobj).then((userObj)=>{

             //product  creation handling

 }).catch((errorProduct)=>{

             //product  creation error handling
 });

       }).catch((error)=>{

         //user creation error handling
});

我的 productobj 是属于User的json对象数组。 当仅是一种产品时,它可以正常工作,但是当有多种产品时,它会失败。因此,我想知道是否可以使用任何方法从同一用户批量创建这些产品。 我可能做错了方法。因此,如果有更好的方法,那么我将不胜感激。谢谢您的帮助。

2 个答案:

答案 0 :(得分:0)

关联user.hasMany(Product)将为User模型添加以下方法。

/**
 * The addAssociations mixin applied to models with hasMany.
 * An example of usage is as follows:
 *
 * ```js
 *
 * User.hasMany(Role);
 *
 * interface UserInstance extends Sequelize.Instance<UserInstance, UserAttributes>, UserAttributes {
 *  // getRoles...
 *  // setRoles...
 *  addRoles: Sequelize.HasManyAddAssociationsMixin<RoleInstance, RoleId>;
 *  // addRole...
 *  // createRole...
 *  // removeRole...
 *  // removeRoles...
 *  // hasRole...
 *  // hasRoles...
 *  // countRoles...
 * }
 * ```
 *
 * @see https://sequelize.org/master/class/lib/associations/has-many.js~HasMany.html
 * @see Instance
 */

对于您的情况,应使用userModel.addProducts(productModels)。例如

import { sequelize } from '../../db';
import { Model, DataTypes, HasManyAddAssociationsMixin } from 'sequelize';

class User extends Model {
  public addProducts!: HasManyAddAssociationsMixin<Product, number>;
}
User.init(
  {
    email: {
      type: DataTypes.STRING,
      unique: true,
    },
  },
  { sequelize, modelName: 'users' },
);

class Product extends Model {}
Product.init(
  {
    name: DataTypes.STRING,
  },
  { sequelize, modelName: 'products' },
);

User.hasMany(Product);
Product.belongsTo(User);

(async function test() {
  try {
    await sequelize.sync({ force: true });
    // seed
    await User.create(
      {
        email: 'example@gmail.com',
        products: [{ name: 'apple' }, { name: 'amd' }],
      },
      { include: [Product] },
    );
    // add another two products for this user
    const SomeID = 1;
    const productobj = [{ name: 'nvidia' }, { name: 'intel' }];
    const productModels = await Product.bulkCreate(productobj);
    const userObj = await User.findOne({ where: { id: SomeID } });
    await userObj.addProducts(productModels);
  } catch (error) {
    console.log(error);
  } finally {
    await sequelize.close();
  }
})();

数据库中的数据行:

=# select * from users;
 id |       email
----+-------------------
  1 | example@gmail.com
(1 row)

node-sequelize-examples=# select * from products;
 id |  name  | userId
----+--------+--------
  1 | apple  |      1
  2 | amd    |      1
  3 | nvidia |      1
  4 | intel  |      1
(4 rows)

注意:这些方法仅接受目标模型作为其参数,是纯JavaScript对象或对象数组。您需要bulkCreate个产品。然后,使用userModel.addProducts(productModels)将这些产品与此用户相关联

答案 1 :(得分:0)

似乎this is not supported(尽管自2015年以来一直要求)。我们有一些解决方法:

  1. 如果模型定义允许,则可以按照slideshowp2的答案进行操作:批量创建产品,然后将其分配给用户。如果您在customerId列上允许使用null(这可能不是一个好主意),则此方法将无效。

  2. 如果您知道userId,则可以在要创建的每个产品项中包含此ID,然后使用Products.bulkCreate()。这会起作用。

  3. 针对用户分别创建每个产品。有多种方法可以做到这一点,例如

    Promise.all( productArray.map((prod)=> { 返回user.createProduct(prod) }))