Sequelize, convert entity to plain object

后端 未结 9 1113
说谎
说谎 2020-12-12 16:53

I\'m not very familiar with javascript, and stunning, because i can\'t add new property, to object, that fetched from database using ORM names Sequelize.js.

To avoid

相关标签:
9条回答
  • 2020-12-12 17:22

    Here's what I'm using to get plain response object with non-stringified values and all nested associations from sequelize v4 query.

    With plain JavaScript (ES2015+):

    const toPlain = response => {
      const flattenDataValues = ({ dataValues }) => {
        const flattenedObject = {};
    
        Object.keys(dataValues).forEach(key => {
          const dataValue = dataValues[key];
    
          if (
            Array.isArray(dataValue) &&
            dataValue[0] &&
            dataValue[0].dataValues &&
            typeof dataValue[0].dataValues === 'object'
          ) {
            flattenedObject[key] = dataValues[key].map(flattenDataValues);
          } else if (dataValue && dataValue.dataValues && typeof dataValue.dataValues === 'object') {
            flattenedObject[key] = flattenDataValues(dataValues[key]);
          } else {
            flattenedObject[key] = dataValues[key];
          }
        });
    
        return flattenedObject;
      };
    
      return Array.isArray(response) ? response.map(flattenDataValues) : flattenDataValues(response);
    };
    

    With lodash (a bit more concise):

    const toPlain = response => {
      const flattenDataValues = ({ dataValues }) =>
        _.mapValues(dataValues, value => (
          _.isArray(value) && _.isObject(value[0]) && _.isObject(value[0].dataValues)
            ? _.map(value, flattenDataValues)
            : _.isObject(value) && _.isObject(value.dataValues)
              ? flattenDataValues(value)
              : value
        ));
    
      return _.isArray(response) ? _.map(response, flattenDataValues) : flattenDataValues(response);
    };
    

    Usage:

    const res = await User.findAll({
      include: [{
        model: Company,
        as: 'companies',
        include: [{
          model: Member,
          as: 'member',
        }],
      }],
    });
    
    const plain = toPlain(res);
    
    // 'plain' now contains simple db object without any getters/setters with following structure:
    // [{
    //   id: 123,
    //   name: 'John',
    //   companies: [{
    //     id: 234,
    //     name: 'Google',
    //     members: [{
    //       id: 345,
    //       name: 'Paul',
    //     }]
    //   }]
    // }]
    
    0 讨论(0)
  • 2020-12-12 17:26

    I have found a solution that works fine for nested model and array using native JavaScript functions.

    var results = [{},{},...]; //your result data returned from sequelize query
    var jsonString = JSON.stringify(results); //convert to string to remove the sequelize specific meta data
    
    var obj = JSON.parse(jsonString); //to make plain json
    // do whatever you want to do with obj as plain json
    
    0 讨论(0)
  • 2020-12-12 17:27

    For those coming across this question more recently, .values is deprecated as of Sequelize 3.0.0. Use .get() instead to get the plain javascript object. So the above code would change to:

    var nodedata = node.get({ plain: true });
    

    Sequelize docs here

    0 讨论(0)
  • 2020-12-12 17:27

    you can use map function. this is worked for me.

    db.Sensors
        .findAll({
            where: { nodeid: node.nodeid }
         })
        .map(el => el.get({ plain: true }))
        .then((rows)=>{
            response.json( rows )
         });
    
    0 讨论(0)
  • 2020-12-12 17:28

    Best and the simple way of doing is :

    Just use the default way from Sequelize

    db.Sensors.findAll({
        where: {
            nodeid: node.nodeid
        },
        raw : true // <----------- Magic is here
    }).success(function (sensors) {
            console.log(sensors);
    });
    

    Note : [options.raw] : Return raw result. See sequelize.query for more information.


    For the nested result/if we have include model , In latest version of sequlize ,

    db.Sensors.findAll({
        where: {
            nodeid: node.nodeid
        },
        include : [
            { model : someModel }
        ]
        raw : true , // <----------- Magic is here
        nest : true // <----------- Magic is here
    }).success(function (sensors) {
            console.log(sensors);
    });
    
    0 讨论(0)
  • 2020-12-12 17:29

    If I get you right, you want to add the sensors collection to the node. If you have a mapping between both models you can either use the include functionality explained here or the values getter defined on every instance. You can find the docs for that here.

    The latter can be used like this:

    db.Sensors.findAll({
      where: {
        nodeid: node.nodeid
      }
    }).success(function (sensors) {
      var nodedata = node.values;
    
      nodedata.sensors = sensors.map(function(sensor){ return sensor.values });
      // or
      nodedata.sensors = sensors.map(function(sensor){ return sensor.toJSON() });
    
      nodesensors.push(nodedata);
      response.json(nodesensors);
    });
    

    There is chance that nodedata.sensors = sensors could work as well.

    0 讨论(0)
提交回复
热议问题