【问题标题】:Bulk Insertion in Sequelize hasMany() AssociationSequelize hasMany() 关联中的批量插入
【发布时间】:2020-11-01 12:58:55
【问题描述】:

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

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

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

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 是一个 json 对象数组,属于 User。 当它只有一种产品时它工作正常,但当有多个产品时它就失败了。所以我想知道是否有任何方法可以用来从同一用户批量创建这些产品。 我可能做错了。因此,如果有更好的方法,我将不胜感激。感谢您的帮助。

【问题讨论】:

    标签: node.js model sequelize.js associations


    【解决方案1】:

    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) 将这些产品与该用户关联

    【讨论】:

    • Product.bulkCreate() 通常会在这里失败:如果没有父用户,即使作为中间步骤,也无法创建产品。数据库不知道您要将它们添加到用户。创建无用户产品会违反userId 列上的notNull 约束
    【解决方案2】:

    目前看来this is not supported (尽管自 2015 年以来就已请求)。我们有几种解决方法:

    1. 如果您的模型定义允许,您可以像 slideshowp2 的回答那样做:批量创建产品,然后将它们分配给用户。如果您在 customerId 列上允许空值,这将不起作用(这可能不是一个好主意)。

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多