我对javascript并不是很熟悉,令人惊叹,因为我无法使用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;
我添加了这一行,但这不起作用
答案 0 :(得分:96)
您可以使用查询选项{raw: true}
来返回原始结果。您的查询应如下所示:
db.Sensors.findAll({
where: {
nodeid: node.nodeid
},
raw: true,
})
答案 1 :(得分:85)
对于那些最近遇到此问题的人来说,自{Sequelize 3.0.0}以来.values
已被弃用。使用.get()
来获取普通的javascript对象。所以上面的代码将改为:
var nodedata = node.get({ plain: true });
在这里发布docs
答案 2 :(得分:34)
如果我说得对,您想要将sensors
集合添加到node
。如果两个模型之间有映射,则可以使用include
功能explained here或每个实例上定义的values
getter。您可以找到文档for that here。
后者可以像这样使用:
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
也有可能发挥作用。
答案 3 :(得分:25)
正如CharlesA在答案中指出的那样,.values()
是technically deprecated,尽管docs中没有明确指出这一事实。如果您不想在查询中使用{ raw: true }
,首选方法是在结果上调用.get()
。
.get()
是实例的方法,而不是数组的方法。如上面链接的问题所述,Sequelize返回实例对象的本机数组(并且维护者不打算更改它),因此您必须自己遍历数组:
db.Sensors.findAll({
where: {
nodeid: node.nodeid
}
}).success((sensors) => {
const nodeData = sensors.map((node) => node.get({ plain: true }));
});
答案 4 :(得分:22)
最好和简单的做法是:
只需使用 Sequelize
中的默认方式即可<?php
if ($this->item->catid == 9) {
echo "yes, it exists";
}
else {
echo "no, it don't exist";
}
?>
注意:[options.raw]:返回原始结果。有关更多信息,请参阅sequelize.query 信息。
答案 5 :(得分:6)
这是我用来获取具有非字符串化值的普通响应对象以及来自sequelize
v4查询的所有嵌套关联的内容。
使用纯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',
// }]
// }]
// }]
答案 6 :(得分:5)
我找到了一个适用于使用本机JavaScript函数的嵌套模型和数组的解决方案。
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
答案 7 :(得分:4)
或者您可以使用地图功能。这对我有用。像这样:
db.Sensors
.findAll({
where: { nodeid: node.nodeid }
})
.map(el => el.get({ plain: true }))
.then((rows)=>{
response.json( rows )
});
答案 8 :(得分:2)
如果您希望所有查询都发生,您也可以尝试此操作:
var sequelize = new Sequelize('database', 'username', 'password', {query:{raw:true}})
答案 9 :(得分:0)
对于嵌套的JSON纯文本
db.model.findAll({
raw : true ,
nest : true
})
答案 10 :(得分:0)
回答有点晚,但万一有人遇到这个问题并需要解决方案......
(假设这是在 async/await 函数中)
const sensors = JSON.parse(JSON.stringify(await
db.Sensors.findAll({
where: {
nodeid: node.nodeid
}
})))
您可以查询并返回它是一个普通对象、对象数组等...