I just started out creating a hobby app using Flask, mongoengine and
flask-mongoengine. Flask is a Python microframework that allows rapid
flask-mongoengine is a library that allows some
amount of interfacing between Flask and monogoengine.
In the application I had two models defined like this
class Student(db.Document): name = db.StringField(max_length=255, required=True) gen_reg_no = db.ListField(db.EmbeddedDocumentField('RegisterNo')) class RegisterNo(db.Document): register_no = db.IntField(required=True) year = db.IntField(required=True)
What I needed was simple: I wanted to add an attribute to the RegisterNo model. In effect the resulting model would be like this:
class RegisterNo(db.Document): register_no = db.IntField(required=True) year = db.IntField(required=True) section = db.IntField(required=True)
After about two days of googling, I decided to find out with trial and error. It gave some very interesting insights, which was not very apparent from the documentation
First we query the database for the records we need to modify.
The reason we use
gen_reg_no instead of
name is because we need to update
mongoengine will give an error saying ‘The positional operator
did not find the match needed from query’.
Next we use method-chaining to update the document.
mongoengine gives three
methods to update a QuerySet:
update_one() performs an atomic update on the first result matched for the
update() performs updates on all the results matched by the query.
There are several modifiers that can be used with these methods. I used the
update_one() method with the
set modifier sets a particular value. Other modifiers that operate on
individual values are
dec. All other modifiers operate on
So to use the
set modifier, this is what I ended up with
Let me explain this expression:
set__gen_reg_no allows to set the value of gen_reg_no. Since what we really
want to do is update a value in the embedded document which is basically a list
of documents, we need to traverse through the document in the embedded document.
So the final expression becomes:
The addition of the
__S allows us to update list without knowing the index
position(since it is a list).
Something to note is that, you cannot query the attribute you need to change.