Return 来自 sequelize with association 的平面对象

Return flat object from sequelize with association

我正在努力在 sequelize 中转换我的所有查询。 我遇到的问题是,当 select 查询包含关联(例如一对多)时,我得到的对象是一个嵌套对象数组。

它看起来像:

[   
  {
    "field1": "someval",
    "field2": "someval1",
    "assoc_table": {
      "field_a": 1,
      "field_b": "someval"
    }   
  },   
  {
    "field1": "someval",
    "field2": "someval3",
    "assoc_table": {
      "field_a": 5,
      "field_b": "someval"
    }   
  },   
  {
    "field1": "someval",
    "field2": "someval3",
    "assoc_table": {
      "field_a": 12,
      "field_b": "someval"
    }   
   } 
]

我尝试使用不同的模块来展平对象(在一个循环内,每个对象单独),但我总是收到一个错误,告诉我我试图展平的不仅仅是对象。

此外,我更希望避免对象被展平的部分,并通过 sequelize 简单地获得平坦的结果。

sequelize 代码如下所示:

models.table1.findAll({
    attributes: ['field1', 'field2'],
    where: {field1: someval},
    include: [{model: models.assoc_table, required: true, attributes:['field_a', 'field_b']}]
}).then(function (result) {
    res.send(result);
}).catch(function(error) {
    console.log(error);
});

您的部分问题可能是您的 result 是一个模型实例数组,因此如果您没有对数组中的元素调用 toJSON,您可能会遇到展平问题.我提供了可以使您的示例变平的代码:

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]);
        }
    });
});

您还可以添加 raw: true 作为 findAll 的选项,这将使您的对象变平,但它看起来像这样:

[   
  {
    "field1": "someval",
    "field2": "someval1",
    "assoc_table.field_a": 1,
    "assoc_table.field_b": "someval"
  },
  ...
]

使用raw: true 辅助函数可以简化return 键。这将确保没有值被覆盖,并提供一种方法来保留一些基于字符串的嵌套(例如 ID)。

/**
  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
}

老问题,但由于我也尝试这样做并找到了不需要“之后”映射的纯续集解决方案,所以我想在此处添加它。因此,为了让自己 return 成为所需的对象格式,应该是这样的,其中 attributes 是根据 include table 列的 return 值明确分配的]:

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
     }
   ]
})

老问题,但有了新的续集更新,同时使用:

raw:true,
nest:true