【问题标题】:AdonisJS - Update many items from arrayAdonisJS - 从数组中更新许多项目
【发布时间】:2020-04-20 03:32:22
【问题描述】:

所以我在后端使用 AdonisJS 和 PostgreSQL,并且我正在尝试找到一种方法来更新数组中的许多内容,而无需执行循环,无论是通过 SQL 还是使用 AdonisJS 模型方法。

我有一个这样的数组(项目数不定):

[
      {
        "id":5,
        "name":"aaaaaaa",
        "price":"5689.78",
      },

      {
        "id":6,
        "name":"bbbbb",
        "price":"5689.78",
      },

      {
        "id":7,
        "name":"cccc",
        "price":"5689.78",
      }
]

假设我有一个名为 products 的表

【问题讨论】:

    标签: postgresql adonis.js


    【解决方案1】:

    所以我终于让它工作了,我使用了带有 ON CONFLICT 子句的 INSERT 查询

        await Database.raw(
          "INSERT INTO products (id, name, price) " +
          "VALUES (5, 'aaaaaaa', 5689.78), (6, 'bbbbb', 5689.78), (7, 'cccc', 5689.78) " +
          "ON CONFLICT (id) " +
          "DO UPDATE SET " +
          "name = EXCLUDED.name, " +
          "category_id = EXCLUDED.category_id, " +
          "price = EXCLUDED.price, " +
          "units = EXCLUDED.units, " +
          "priority = EXCLUDED.priority, " +
          "is_hidden = EXCLUDED.is_hidden"
        )
    
    

    为了动态更新,我会给出这个示例代码

         const requestPayload = [
          {
            "id":5,
            "name":"aaaaaaa",
            "price":"5689.78",
          },
    
          {
            "id":6,
            "name":"bbbbb",
            "price":"5689.78",
          },
    
          {
            "id":7,
            "name":"cccc",
            "price":"5689.78",
          }
        ]
    
        // create a string that translate the request payload
        // to this format = "(5, 'aaaaaaa', 5689.78), (6, 'bbbbb', 5689.78), (7, 'cccc', 5689.78)"
        const values = requestPayload.reduce((result, item) => {
          const itemKeys = ['id', 'name', 'price']
    
          // create a string that translate the product item obj
          // to this format (4, 'aaaa', 111)
          const productValues = itemKeys.reduce((res, productKey) => {
            const productValue = item[productKey]
    
            if (productKey === 'name') {
              res.push(`'${productValue}'`)
              return res
            }
    
            res.push(`${productValue}`)
    
            return res
          }, []).join(', ')
    
          result.push(`( ${productValues} )`)
          return result
        }, []).join(', ')
    
        await Database.raw(
          "INSERT INTO products (id, name, price) " +
          "VALUES " + values +
          "ON CONFLICT (id) " +
          "DO UPDATE SET " +
          "name = EXCLUDED.name, " +
          "category_id = EXCLUDED.category_id, " +
          "price = EXCLUDED.price, " +
          "units = EXCLUDED.units, " +
          "priority = EXCLUDED.priority, " +
          "is_hidden = EXCLUDED.is_hidden"
        )
    
    

    我觉得使用 UPDATE 语句而不是 INSERT 语句应该有更好的答案,所以如果您有更好的答案,请回答这个问题!

    更新:

    我现在使用 UPDATE 语句创建了一个查询

        await Database.raw(
          "UPDATE products " +
          "SET " +
          "name = prod.name, " +
          "price = prod.price, " +
          "FROM " +
          "( VALUES (5, 'aaaaaaa', 5689.78), (6, 'bbbbb', 5689.78), (7, 'cccc', 5689.78) ) as prod (id, name, price) " +
          "WHERE products.id = prod.id"
        )
    

    【讨论】:

      【解决方案2】:

      您可以使用清晰的视角。

      const Product = use('App/Models/Product')
      
      const productData = request.collect(['id', 'name', 'price'])
      await Product.createMany(productData)
      

      createMany 方法进行 n 查询次数而不是进行批量插入,其中 n 是行数。

      或者您可以使用此代码进行批量插入。您必须明确定义返回列。

      await Database
        .insert(array)
        .into('products')
        .returning('id')
      

      【讨论】:

        猜你喜欢
        • 2013-02-14
        • 2019-01-27
        • 2018-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-13
        • 1970-01-01
        • 2019-12-15
        相关资源
        最近更新 更多