Sequelize, 엔티티를 일반 객체로 변환
저는 자바 스크립트에 익숙하지 않고 놀랍습니다. ORM 이름 Sequelize.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);
});
따라서 일반적으로 객체에 새 속성을 추가하는 방법은 무엇입니까?
도움이된다면 sequelize-postgres 버전 2.0.x를 사용합니다.
upd. 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] } } }
다음으로, "좋아요. 간단합니다. 속성을 dataValues에 추가하기 만하면됩니다."라고 생각합니다.
node.selectedValues.sensors = sensors;
node.dataValues.sensors = sensors;
이 줄을 추가했는데 작동하지 않습니다.
내가 맞다면 sensors
컬렉션을 node
. 두 모델간에 매핑이있는 경우 여기에 설명 된 include
기능을 사용 하거나 모든 인스턴스에 정의 된 getter를 사용할 수 있습니다 . 여기 에서 문서 를 찾을 수 있습니다 .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
작동 할 수 있는 기회 도 있습니다.
쿼리 옵션 {raw: true}
을 사용 하여 원시 결과를 반환 할 수 있습니다. 쿼리는 다음과 같아야합니다.
db.Sensors.findAll({
where: {
nodeid: node.nodeid
},
raw: true,
})
이 질문을 더 최근 .values
에 접하는 사람들을 위해 Sequelize 3.0.0에서 더 이상 사용되지 않습니다. .get()
대신 사용 하여 일반 자바 스크립트 개체를 가져옵니다. 따라서 위의 코드는 다음과 같이 변경됩니다.
var nodedata = node.get({ plain: true });
여기에서 문서 속편
가장 좋고 간단한 방법은 다음과 같습니다.
Sequelize 의 기본 방법을 사용하십시오.
db.Sensors.findAll({
where: {
nodeid: node.nodeid
},
raw : true // <----------- Magic is here
}).success(function (sensors) {
console.log(sensors);
});
참고 : [options.raw] : 원시 결과를 반환합니다. 자세한 내용은 sequelize.query를 참조하십시오.
중첩 된 결과의 경우 / 모델을 포함하는 경우 최신 버전의 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);
});
As CharlesA notes in his answer, .values()
is technically deprecated, though this fact isn't explicitly noted in the docs. If you don't want to use { raw: true }
in the query, the preferred approach is to call .get()
on the results.
.get()
, however, is a method of an instance, not of an array. As noted in the linked issue above, Sequelize returns native arrays of instance objects (and the maintainers don't plan on changing that), so you have to iterate through the array yourself:
db.Sensors.findAll({
where: {
nodeid: node.nodeid
}
}).success((sensors) => {
const nodeData = sensors.map((node) => node.get({ plain: true }));
});
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',
// }]
// }]
// }]
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 )
});
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
참고URL : https://stackoverflow.com/questions/21961818/sequelize-convert-entity-to-plain-object
'Development Tip' 카테고리의 다른 글
ImageView가 동적 너비를 가진 정사각형입니까? (0) | 2020.10.30 |
---|---|
해시 특정 키를 제외하고 모두 제거 (0) | 2020.10.30 |
라이브러리가로드되지 않음 : /usr/local/opt/readline/lib/libreadline.7.dylib (0) | 2020.10.30 |
Android Studio에서 앱을 디버그 할 수 없음 (0) | 2020.10.30 |
lxml 설치 오류 우분투 14.04 (내부 컴파일러 오류) (0) | 2020.10.30 |