Return flat object from sequelize with association

后端 未结 3 1947
醉梦人生
醉梦人生 2021-01-14 08:21

I am working on converting all my queries in sequelize. The problem I have come across is that when select queries include associations (ex. one to many), the object I get

相关标签:
3条回答
  • 2021-01-14 09:05

    Old question, but as I was attempting to do this also and found a pure sequelize solution that does not require the "after" mapping, I wanted to add that here. So to have sequelize itself return the desired object format, it would be this, where the attributes are explicitly assigned based off column return values from the include table:

    models.table1.findAll({
        attributes: [
          'field1', 
          'field2',
          [sequelize.col('models.assoc_table.field_a'), 'field_a'], // Set key
          [sequelize.col('models.assoc_table.field_b'), 'field_b'], // Set key
        ],
        where: {field1: someval},
        include: [
         {model: models.assoc_table, 
          required: true, 
          attributes:[], // Explicitly do not send back nested key's
         }
       ]
    })
    
    0 讨论(0)
  • 2021-01-14 09:11

    Part of your issue is probably that your result is an array of model instances, so you might be having issues flattening it if you didn't call toJSON on the elements in the array. I provided code that would flatten your example:

    result.forEach(obj => { 
        Object.keys(obj.toJSON()).forEach(k => {
            if (typeof obj[k] === 'object') {       
                Object.keys(obj[k]).forEach(j => obj[j] = obj[k][j]);
            }
        });
    });
    

    You can also add raw: true as an option to findAll, which will flatten your object, but it will look like this:

    [   
      {
        "field1": "someval",
        "field2": "someval1",
        "assoc_table.field_a": 1,
        "assoc_table.field_b": "someval"
      },
      ...
    ]
    
    0 讨论(0)
  • 2021-01-14 09:22

    Using raw: true a helper function can simplify the return keys. This will make sure no values are over-written and gives a way to keep some of string-based nesting (IDs for example).

    /**
      Simplify keys returned by a sequelize {raw: true} query. Makes sure no values
      are over-written and gives a way to keep some of string-based nesting (IDs for
      example).
    
      @example result.map(r => trimKeys(r))
    */
    function trimKeys(obj, deepin = ['id']) {
      const keys = Object.keys(obj)
      const ret = {}
      for (var i = 0; i < keys.length; i++) {
        const key = keys[i]
        const keyParts = key.split('.')
        let idx = 1
        let newKey = keyParts[keyParts.length - idx]
        while((ret[newKey] || deepin.find(d => newKey === d)) && idx >= 0) {
          idx++
          newKey = keyParts[keyParts.length - idx] + '.' + newKey
        }
        ret[newKey] = obj[key]
      }
      return ret
    }
    
    0 讨论(0)
提交回复
热议问题