prosource

연속화, 도면요소를 일반 객체로 변환

probook 2023. 8. 1. 20:37
반응형

연속화, 도면요소를 일반 객체로 변환

저는 Javascript에 익숙하지 않고 놀랍습니다. 왜냐하면 ORM 이름 Sequetize.js를 사용하여 데이터베이스에서 가져온 새 속성을 개체에 추가할 수 없기 때문입니다.

이를 피하기 위해 다음 해킹을 사용합니다.

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

일반적으로 새 속성을 개체에 추가하는 방법입니다.

도움이 될 수 있다면, 저는 속편화-포스트그레스 버전 2.0.x를 사용합니다.

update.console.log(노드):

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

다음으로 여러분이 생각하는 것은 다음과 같습니다. "좋아요, 그건 쉬워요. 그냥 데이터 값에 속성을 추가하세요."

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

제가 이 대사를 추가했는데, 이것은 작동하지 않습니다.

쿼리 옵션을 사용할 수 있습니다.{raw: true}원시 결과를 반환합니다.쿼리는 다음과 같습니다.

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

또한 당신이 연관이 있는 경우.include납작해지는 것.그래서 다른 매개 변수를 사용할 수 있습니다.nest:true

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

최근에 이 질문을 접한 분들은.valuesSufficialize 3.0.0에서 더 이상 사용되지 않습니다..get()대신 일반 자바스크립트 객체를 가져옵니다.따라서 위의 코드는 다음으로 변경됩니다.

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

여기서 문서 후속 처리

가장 좋고 간단한 방법은 다음과 같습니다.

Sequetize의 기본 방법을 사용합니다.

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

참고 : [options.raw] : 원시 결과를 반환합니다.속편 참조.자세한 내용은 를 참조하십시오.


내포된 결과의 경우/포함 모델이 있는 경우, 최신 버전의 sequize,

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

만약 내가 당신을 맞추면, 당신은 추가하기를 원합니다.sensors로의 기부금.node두 모델 사이에 매핑이 있는 경우 다음 중 하나를 사용할 수 있습니다.include여기에 설명된 기능 또는values모든 인스턴스에 대해 더 잘 정의됩니다.당신은 여기에서 그것에 대한 문서를 찾을 수 있습니다.

후자는 다음과 같이 사용할 수 있습니다.

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

의 가능성이 있습니다.nodedata.sensors = sensors효과가 있을 수도 있습니다.

찰스 A가 그의 대답에서 지적했듯이,.values()기술적으로는 더 이상 사용되지 않지만, 이 사실은 문서에 명시되어 있지 않습니다.사용하지 않으려는 경우{ raw: true }쿼리에서 선호하는 접근 방식은 호출하는 것입니다..get()결과에 따라

.get()그러나 는 배열이 아닌 인스턴스의 메서드입니다.위의 링크된 문제에서 언급한 바와 같이 Sequetize는 인스턴스 개체의 기본 배열을 반환합니다(유지 관리자는 이를 변경할 계획이 없습니다). 따라서 사용자가 직접 배열을 반복해야 합니다.

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

지도 기능을 사용할 수 있습니다.이것은 나에게 효과가 있습니다.

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

다음은 문자열화되지 않은 값과 모든 중첩된 연결을 가진 일반 응답 개체를 가져오는 데 사용하는 방법입니다.sequelizev4 쿼리입니다.

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

Lodash(조금 더 간결함)를 사용한 경우:

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

용도:

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

네이티브 자바스크립트 함수를 사용하여 중첩된 모델과 배열에 적합한 솔루션을 찾았습니다.

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

일반 객체의 경우

db.model.findAll({
  raw : true ,
  nest : true
})

모든 쿼리에 대해 수행하려는 경우에도 이 작업을 수행할 수 있습니다.

var sequelize = new Sequelize('database', 'username', 'password', {query:{raw:true}})

방문 모든 쿼리를 원시 = 실제 후속편으로 설정

대답하기엔 좀 늦었지만 누군가가 이 질문을 우연히 발견하고 해결책이 필요할 경우를 대비해서...

(비동기/대기 기능으로 가정)

const sensors = JSON.parse(JSON.stringify(await 
    db.Sensors.findAll({
    where: {
        nodeid: node.nodeid
    }
})))

일반 개체, 개체 배열 등을 쿼리하고 반환할 수 있습니다.

편리한 응답을 위해 나만의 모델 믹스인을 사용합니다.

const camelcaseKeys = require('camelcase-keys');

const initMixins = Sequelize => {
    // Convert model to plain object and camelcase keys for response
    Sequelize.Model.prototype.toPlainObject = function({ camelcase = false } = {}) {
        const plain = this.get({ plain: true });
        if (camelcase) {
            return camelcaseKeys(plain, { deep: true });
        } else {
            return plain;
        }
    };
};

module.exports = {
    initMixins,
};
// usage
const userModel = await UserModel.findOne();
console.log(userModel.toPlainObject());

언급URL : https://stackoverflow.com/questions/21961818/sequelize-convert-entity-to-plain-object

반응형