首页 > 解决方案 > Mongoengine : How to update specific fields of an existing document?

问题描述

I have an existing mongo document which has been exposed over a REST API. The API request will contain certain fields from the document which either needs to be updated with new values or insert new values in them if the field is null. How to perform the update on fields of an existing mongoengine document? I'm using marshmallow-mongoengine for serialization on flask.

The problem that I'm facing is that if a certain field is missing in the request payload, on calling update with the remaining fields as kwargs leads to setting the missing fields as None. How can update or insert only the fields given in the payload?

标签: flaskmongoenginemarshmallow

解决方案


约瑟夫的回答是好的。但另一个答案不会伤害呃!

这是我使用flask-mongoengine 更新我的文档的方法

实际代码:

Game.objects(id = _id).update(
        set__kickoff = request_json.get('kickoff'),
        set__gameid = request_json.get('gameid'),
        set__home_team = request_json.get('home_team'),
        set__away_team = request_json.get('away_team'),
        set__home_win = request_json.get('home_win'),
        set__draw = request_json.get('draw'),
        set__away_win = request_json.get('away_win'),
        set__sport = request_json.get('sport')
        )

Game class : 

    import datetime
    flask_mongoengine import BaseQuerySet, MongoEngine
    db = MongoEngine()

    class Game(db.Document):
    kickoff  = db.DateTimeField(required=True)
    added_on  = db.DateTimeField(default=datetime.datetime.utcnow)
    gameid = db.FloatField(required=True)     
    home_team = db.StringField(required=True)
    home_win = db.FloatField(required=True)    
    draw = db.FloatField(required=True)
    away_win = db.FloatField(required=True)
    away_team = db.StringField(required=True)
    sport = db.StringField(required=True) 
    meta = {
        'collection':'games',
        'queryset_class': BaseQuerySet
    }

PS:记得在python中缩进代码

此外,我注意到您在问题中标记了 Marshmallow。这里,一个来自他们的官方 git repo 的示例 这里

首先我们需要一个 Mongoengine 文档:

import mongoengine as me

class Task(me.EmbeddedDocument):
    content = me.StringField(required=True)
    priority = me.IntField(default=1)


class User(me.Document):
    name = me.StringField()
    password = me.StringField(required=True)
    email = me.StringField()
    tasks = me.ListField(me.EmbeddedDocumentField(Task))

伟大的 !现在是 Marshmallow Schema 的时候了。为了保持 DRY,我们使用 marshmallow-mongoengine 进行映射:

import marshmallow_mongoengine as ma

class UserSchema(ma.ModelSchema):
    class Meta:
        model = User

最后是时候使用我们的模式来加载/转储文档了:首先让我们创建一个文档

user_schema = UserSchema()
u, errors = user_schema.load({"name": "John Doe", "email": 
      "jdoe@example.com", "password": "123456","tasks": [{"content": "Find a 
      proper password"}]})
u.save()

如果文档已经存在,我们可以使用 update 更新它

u
u2, errors = user_schema.update(u, {"name": "Jacques Faite"})
>>> u2.name
"Jacques Faite"

推荐阅读