Vraag Sequelize, converteer entiteit naar gewoon object


Ik ben niet bekend met javascript en verbluffend, omdat ik geen nieuwe eigenschap, aan object, kan toevoegen die ik uit de database heb opgehaald met behulp van ORM-namen Sequelize.js.

Om dit te voorkomen, gebruik ik deze hack:

db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    }
}).success(function (sensors) {
        var nodedata = JSON.parse(JSON.stringify(node)); // this is my trick
        nodedata.sensors = sensors;
        nodesensors.push(nodedata);
        response.json(nodesensors);
});

Dus, welke normale manier om nieuwe eigenschappen toe te voegen aan het object.

Als het kan helpen, gebruik ik de nieuwe versie 2.0.x van sequelize-postgres.

upd. console.log (knooppunt):

{ dataValues: 
   { nodeid: 'NodeId',
     name: 'NameHere',
     altname: 'Test9',
     longname: '',
     latitude: 30,
     longitude: -10,
     networkid: 'NetworkId',
     farmid: '5',
     lastheard: Mon Dec 09 2013 04:04:40 GMT+0300 (FET),
     id: 9,
     createdAt: Tue Dec 03 2013 01:29:09 GMT+0300 (FET),
     updatedAt: Sun Feb 23 2014 01:07:14 GMT+0300 (FET) },
  __options: 
   { timestamps: true,
     createdAt: 'createdAt',
     updatedAt: 'updatedAt',
     deletedAt: 'deletedAt',
     touchedAt: 'touchedAt',
     instanceMethods: {},
     classMethods: {},
     validate: {},
     freezeTableName: false,
     underscored: false,
     syncOnAssociation: true,
     paranoid: false,
     whereCollection: { farmid: 5, networkid: 'NetworkId' },
     schema: null,
     schemaDelimiter: '',
     language: 'en',
     defaultScope: null,
     scopes: null,
     hooks: { beforeCreate: [], afterCreate: [] },
     omitNull: false,
     hasPrimaryKeys: false },
  hasPrimaryKeys: false,
  selectedValues: 
   { nodeid: 'NodeId',
     name: 'NameHere',
     longname: '',
     latitude: 30,
     longitude: -110,
     networkid: 'NetworkId',
     farmid: '5',
     lastheard: Mon Dec 09 2013 04:04:40 GMT+0300 (FET),
     id: 9,
     createdAt: Tue Dec 03 2013 01:29:09 GMT+0300 (FET),
     updatedAt: Sun Feb 23 2014 01:07:14 GMT+0300 (FET),
     altname: 'Test9' },
  __eagerlyLoadedAssociations: [],
  isDirty: false,
  isNewRecord: false,
  daoFactoryName: 'Nodes',
  daoFactory: 
   { options: 
      { timestamps: true,
        createdAt: 'createdAt',
        updatedAt: 'updatedAt',
        deletedAt: 'deletedAt',
        touchedAt: 'touchedAt',
        instanceMethods: {},
        classMethods: {},
        validate: {},
        freezeTableName: false,
        underscored: false,
        syncOnAssociation: true,
        paranoid: false,
        whereCollection: [Object],
        schema: null,
        schemaDelimiter: '',
        language: 'en',
        defaultScope: null,
        scopes: null,
        hooks: [Object],
        omitNull: false,
        hasPrimaryKeys: false },
     name: 'Nodes',
     tableName: 'Nodes',
     rawAttributes: 
      { nodeid: [Object],
        name: [Object],
        altname: [Object],
        longname: [Object],
        latitude: [Object],
        longitude: [Object],
        networkid: [Object],
        farmid: [Object],
        lastheard: [Object],
        id: [Object],
        createdAt: [Object],
        updatedAt: [Object] },
     daoFactoryManager: { daos: [Object], sequelize: [Object] },
     associations: {},
     scopeObj: {},
     primaryKeys: {},
     primaryKeyCount: 0,
     hasPrimaryKeys: false,
     autoIncrementField: 'id',
     DAO: { [Function] super_: [Function] } } }

Vervolgens denk ik wat je denkt: "Ok, dat is eenvoudig, voeg gewoon je eigendom toe aan dataValues."

node.selectedValues.sensors = sensors;
node.dataValues.sensors = sensors;

Ik voeg deze regels toe, en dit werkt niet


45
2018-02-22 23:02


oorsprong


antwoorden:


Als ik je goed begrijp, wil je de sensors verzamelen voor de node. Als u een koppeling tussen beide modellen hebt, kunt u de include functionaliteit uitgelegd hier of de values getter gedefinieerd op elk exemplaar. U kunt de documenten vinden voor dat hier.

Dit laatste kan als volgt worden gebruikt:

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

Er is een kans dat nodedata.sensors = sensors zou ook kunnen werken.


26
2018-02-24 08:07



u kunt de vraagopties gebruiken {raw: true} om het onbewerkte resultaat te retourneren. Uw zoekopdracht zou als volgt moeten zijn:

db.Sensors.findAll({
  where: {
    nodeid: node.nodeid
  },
  raw: true,
})

76
2018-06-12 06:35



Voor degenen die deze vraag recenter tegenkwamen, .values wordt beëindigd vanaf Sequelize 3.0.0. Gebruik .get() in plaats daarvan om het eenvoudige javascript-object te krijgen. Dus de bovenstaande code zou veranderen in:

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

Sequelize docs hier


65
2017-09-16 12:21



Zoals CharlesA opmerkt in zijn antwoord, .values() is technisch verouderd, hoewel dit feit niet expliciet wordt vermeld in de docs. Als je niet wilt gebruiken { raw: true } in de query is de voorkeursbenadering bellen .get() over de resultaten.

.get()is echter een methode van een instantie, niet van een array. Zoals opgemerkt in het gelinkte probleem hierboven, retourneert Sequelize native arrays van instantie-objecten (en de beheerders zijn niet van plan dat te veranderen), dus u moet zelf de array doorlopen:

db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    }
}).success((sensors) => {
    const nodeData = sensors.map((node) => node.get({ plain: true }));
});

15
2018-02-02 16:32



Beste en eenvoudige manier om te doen is:

Gebruik gewoon de standaardmanier van Sequelize

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

Opmerking: [options.raw]: ruw resultaat retourneren. Zie sequelize.query voor meer informatie   informatie.


11
2018-04-14 12:18



Dit is wat ik gebruik om een ​​duidelijk antwoordobject te krijgen met niet-stringified waarden en alle geneste associaties van sequelize v4-query.

Met gewoon 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);
};

Met lodash (een beetje beknopter):

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

Gebruik:

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',
//     }]
//   }]
// }]

2
2017-11-09 14:20



Ik heb een oplossing gevonden die prima werkt voor genest model en array met behulp van native JavaScript-functies.

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

1
2018-03-16 19:06



of je kunt de kaartfunctie gebruiken. dit is voor mij gewerkt. soortgelijk :

db.Sensors
    .findAll({
        where: { nodeid: node.nodeid }
     })
    .map(el => el.get({ plain: true }))
    .then((rows)=>{
        response.json( rows )
     });

1
2018-03-29 16:31