postgresql 向 Sequelize FindOne 返回的对象添加属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38426683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Add Property to Object that is returned by Sequelize FindOne
提问by Rastalamm
I am trying to add a property to a sequelize instance before passing it back to the client.
我正在尝试将一个属性添加到 sequelize 实例,然后再将其传回客户端。
router.get('/cats/1', function (req, res) {
Cat.findOne({where: {id: 1}})
.then(function (cat) {
// cat exists and looks like {id: 1}
cat.name = "Lincoln";
// console.log of cat is {id: 1, name: Lincoln}
res.json(cat);
});
});
The client only see's {id: 1}
and not the newly added key.
客户端只能看到 's{id: 1}
而不是新添加的密钥。
- What is going on here?
- What type of Object is returned by Sequelize?
- How can I add new properties to my Cats and send them back?
- 这里发生了什么?
- Sequelize 返回什么类型的对象?
- 如何为我的猫添加新属性并将它们发送回来?
回答by Tom Jardine-McNamara
The Sequelize Model
class (of which your cats are instances) has a toJSON()
method which res.json will presumably use to serialise your cats. The method returns the result of Model#get()
(https://github.com/sequelize/sequelize/blob/95adb78a03c16ebdc1e62e80983d1d6a204eed80/lib/model.js#L3610-L3613), which only uses attributes defined on the model. If you want to be able to set the cats name, but not store names in the DB, you can use a virtual column when defining your cat model:
SequelizeModel
类(您的猫就是其中的实例)有一个toJSON()
方法, res.json 可能会用它来序列化您的猫。该方法返回Model#get()
(https://github.com/sequelize/sequelize/blob/95adb78a03c16ebdc1e62e80983d1d6a204eed80/lib/model.js#L3610-L3613)的结果,该结果仅使用模型上定义的属性。如果您希望能够设置猫的名称,但不将名称存储在数据库中,则可以在定义猫模型时使用虚拟列:
sequelize.define('Cat', {
// [other columns here...]
name: Sequelize.VIRTUAL
});
Alternatively, if you don't want to add properties to the model definition:
或者,如果您不想向模型定义添加属性:
cat = cat.toJSON(); // actually returns a plain object, not a JSON string
cat.name = 'Macavity';
res.json(cat);
回答by Eric Xin Zhang
The following works for sequelize v4.
以下适用于 sequelize v4。
...
const order = Order.findOne(criteria);
order.setDataValue('additionalProperty', 'some value');
...
Hope this helps. It's a bit late but in case people are still looking for answers.
希望这可以帮助。这有点晚了,但以防万一人们仍在寻找答案。
回答by Om Sharma
you can use toJSON()to convert Sequelize object into JSON type and then add properties as we do in js
您可以使用toJSON()将 Sequelize 对象转换为 JSON 类型,然后像我们在 js 中所做的那样添加属性
Example :
例子 :
UserModel.findById(req.params.id)
.then(function (userIns) {
// here userIns is Sequelize Object
// and data is Json Object
let data = userIns.toJSON();
data['displayName'] = 'John';
})
回答by James Cori
It won't let me comment on the correct answer above (https://stackoverflow.com/a/38469390/562683), just wanted to add a use case where this helped me.
它不会让我评论上面的正确答案(https://stackoverflow.com/a/38469390/562683),只是想添加一个对我有帮助的用例。
I have an existing mysql database that we cannot change the schema of (has to work with the old system and the new system until we can deprecate the old system) but we've layered MonogoDB as well for additional features until we can do a system refactor.
我有一个现有的 mysql 数据库,我们无法更改其架构(必须使用旧系统和新系统,直到我们可以弃用旧系统),但我们已经对 MonogoDB 以及附加功能进行了分层,直到我们可以做一个系统重构。
The answer above of the Virtual property helped because i'd basically make a placeholder for the mongo db information (in this case, an object activity log) and add it on the 'findMyObject' service call.
上面 Virtual 属性的答案有所帮助,因为我基本上会为 mongo db 信息(在本例中为对象活动日志)创建一个占位符,并将其添加到“findMyObject”服务调用中。
For example:
例如:
const model = sequelize.define('myobj', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
primaryKey: true,
field: 'eventId',
},
name: { type: Sequelize.STRING, allowNull: false },
history: Sequelize.VIRTUAL,
...
}
Then in the MyObjectService, findMyObject call:
然后在 MyObjectService 中,findMyObject 调用:
...
const result = yield MyObject.findOne(query);
result.history = yield getMyObjectHistoryArray(id);
return result;
And the resultant JSON looks like:
结果 JSON 如下所示:
{
"id": 1,
"name": "My Name",
"history": [
{...},
{...},
]
}
So we were able to extend the object without changing the db, but still have an object in the backend where you can go:
所以我们能够在不更改数据库的情况下扩展对象,但在后端仍然有一个对象可以去:
let obj = yield findMyObject(id);
obj.name = "New Name";
return yield obj.save();
Which you wouldn't be able to do if, in the findMyObject function, you either did {raw: true}
or result.get({plain: true})
你就不能当,做的findMyObject功能,你要么做{raw: true}
或result.get({plain: true})
回答by 7hibault
What works for me is to use setDataValue
对我有用的是使用 setDataValue
router.get('/cats/1', function (req, res) {
Cat.findOne({where: {id: 1}})
.then(function (cat) {
cat.setDataValue("name", "Lincoln");
res.json(cat);
});
});
Specs for the function
功能规格
public setDataValue(key: string, value: any)
Update the underlying data value
Params:
Name Type Attribute Description
key string key to set in instance data store
value any new value for given key
Source: https://sequelize.org/master/class/lib/model.js~Model.html#instance-method-setDataValue
来源:https: //sequelize.org/master/class/lib/model.js~Model.html#instance-method-setDataValue