Weird thing to understand from mongoengine in Flask

Inital mongo collection

I am creation a mongo dument in Flask using MongoEngine Object mapper.Simple, consider the collection name is TestMe and it has two fields (name, address).
The name of the document is nava.

from mongoengine import Document, connect, StringField


class TestMe(Document):
    name = StringField(required=True)
    address = StringField(required=True)

Adding a new row

I am adding one row document in the collection using this mongoengine class which is described below.

 # 1. Initial document creation in mongo collections with only two fields(name and address)                                                        
    t = TestMe(name="Navaneethan", address="Bangalore")

So, the document is added successfully.

Verify in your mongo client

For quick confirmation, We can verify the document in mongod client.

(hire)navaneethan@navaneethLap:~/workspace/experiments/python/flask$ mongo
MongoDB shell version: 3.0.4
connecting to: test
Server has startup warnings: 
2015-07-30T10:19:08.103+0530 I CONTROL  [initandlisten] 
2015-07-30T10:19:08.103+0530 I CONTROL  [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2015-07-30T10:19:08.103+0530 I CONTROL  [initandlisten] **        We suggest setting it to 'never'
2015-07-30T10:19:08.103+0530 I CONTROL  [initandlisten] 
> show dbs;
employee  0.078GB
hirenew   0.078GB
local     0.078GB
nava      0.078GB
> use nava;
switched to db nava
> db.t
db.test_me          db.toLocaleString(  db.toString(        db.tojson(
> db.test_me.find()
{ "_id" : ObjectId("55b9bf94aff2d3212702a517"), "name" : "Navaneethan", "address" : "Bangalore" }

Adding a new field in the existing collection

Now I need a field has to be added in the existing db nava, which is is_active a booleanfield.
So, the refined model is,

class TestMe(Document):
    name = StringField(required=True)
    address = StringField(required=True)
    is_active = BooleanField(default=False)

To my current scenario, I have to update the field to the selected objects which would have the default value, but it should be reflected in db.

Updating the default value to the exisiting rows for the new field

in my python shell

obj = TestMe.objects(name='Navaneethan').first()
obj.is_active = False
print "updated successfully"

I am retrieving all the fields from the db and updating to the default value.The save happens successfully.

Verifying in the mongod client

But what surprising me is,
Unable to see the new field in mongo db.

switched to db nava
> db.test_me.find()
{ "_id" : ObjectId("55b9bf94aff2d3212702a517"), "name" : "Navaneethan", "address" : "Bangalore" }


Here I scrateched my head for almost 2 hours.

Changing the default value to some new value(false –> true)

After somepoint, tried to update the field with different value(not the default one)

obj = TestMe.objects(name='Navaneethan').first()
obj.is_active = True  # note here the default value of the field is changed
print "updated successfully"


Verifying in the mongod client

The field is updated to the existing rows.

> db.test_me.find()
{ "_id" : ObjectId("55b9bf94aff2d3212702a517"), "name" : "Navaneethan", "address" : "Bangalore", "is_active" : true }

my mind before hitting the head against wall:

It seems little weird to me. Since it is a nosql mapper or what? I come from django experience, I expected the field has to be updated even the default value is given to be updated for the existing rows. But it doesn’t happen. So, what happens is, If the value of the new field changed from the default value(`false` here) to the some other value(`true`) then the update reflects successfully.

There is a solution for every problem.

Yes. This is an obvious statement which I realized after a while hitting my head against the wall.

if you inherit from `DynamicDocument` for mongoengine odm. You will get the clear solution. It does the job.

The learn happens after this post gets published :)

Thanks for your time.


About Navaneethan

mixed feelings...
This entry was posted in Flask, Python and tagged , . Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s