Я не очень хорошо знаком с 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;
Я добавляю эти строки, и это не работает
node.js
sequelize.js
Руслан
источник
источник
node
не должен быть традиционным объектом. Может, это буфер? Чтоconsole.log(node);
написано перед вашим трюком?Ответы:
Если я вас правильно понял, вы хотите добавить
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
это тоже сработает.источник
вы можете использовать параметры запроса,
{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, })
источник
nest: true
вместе сraw: true
.raw:true
глобальную настройку, чтобы нет необходимости передавать ее каждому запросу? СпасибоДля тех, кто столкнулся с этим вопросом в последнее время,
.values
считается устаревшим с Sequelize 3.0.0. Используйте.get()
вместо этого, чтобы получить простой объект javascript. Таким образом, приведенный выше код изменится на:var nodedata = node.get({ plain: true });
Продолжить документы здесь
источник
.get()
не будет преобразовывать включенные ассоциации, используйте.get({ plain: true })
вместо этого. Спасибо, что упомянули предложение из документов.raw: true
Лучший и простой способ сделать это:
Просто используйте способ по умолчанию из Sequelize
db.Sensors.findAll({ where: { nodeid: node.nodeid }, raw : true // <----------- Magic is here }).success(function (sensors) { console.log(sensors); });
Для вложенного результата / если у нас есть модель включения, в последней версии 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); });
источник
sensors
с массивом дочерних элементовsomeModel
, вы получитеarray
поsensors
одномуsomeModel
в каждом.Как CharlesA отмечает в своем ответе,
.values()
является технически устаревшим , хотя этот факт явно не отмечено в документации . Если вы не хотите использовать{ raw: true }
в запросе, предпочтительным подходом является обращение.get()
к результатам..get()
однако это метод экземпляра, а не массива. Как отмечалось в связанной проблеме выше, Sequelize возвращает собственные массивы объектов экземпляра (и специалисты по обслуживанию не планируют это изменять), поэтому вам нужно выполнить итерацию по массиву самостоятельно: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 ) });
источник
results = results.map(el => el.get({ plain: true }))
Я нашел решение, которое отлично работает для вложенных моделей и массивов с использованием собственных функций 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
источник
Вот что я использую для получения простого объекта ответа с нестроковыми значениями и всеми вложенными ассоциациями из
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', // }] // }] // }]
источник
Для вложенного простого текста JSON
db.model.findAll({ raw : true , nest : true })
источник