document.update(**kwargs) writes to MongoDB but not updating fields of document
Seems like batch updating with document.update(**kwargs) only affects DB, not current document. Here is an example:
from mongoengine import *
connect("test")
class SomeDocument(Document):
title = StringField()
def __unicode__(self):
return self.title
SomeDocument.drop_collection()
doc = SomeDocument(title="Initial title")
doc.save()
print "Updating fields one by one and finally save()"
doc = SomeDocument.objects[0]
doc.title = "New title 1"
doc.save()
doc_reloaded = SomeDocument.objects[0]
print "Saved: %s, Loaded: %s" % (doc, doc_reloaded)
print ""
print "Batch updating with document.update(**kwargs)"
doc = SomeDocument.objects[0]
doc.update(**{ "set__title": "New title 2" })
doc_reloaded = SomeDocument.objects[0]
print "Saved: %s, Loaded: %s" % (doc, doc_reloaded)
Output
Updating fields one by one and finally save()
Saved: New title 1, Loaded: New title 1
Updating with update()
Saved: New title 1, Loaded: New title 2
Expected behaviour is to update field's values after performing update().
This isn't currently supported and you have to reload.
Happy to take a PR if you want to implement this behaviour - it would be good
This is certainly a bug. MongoEngine should retrieve the object every time instead of using the cache. If you want to invalidate parts of the cache that's just fine but I prefer correct behaviour over optimizations. @rozza I'm reopening since this is a major issue and someone might want to pick it up (maybe me).
I don't thing this a bug. It is more likely is a feature request. Should it be scheduled for 0.10?
Behavior described in this bug is documented and well known to MongoEngine users and hackers users. Changing this will be backward incompatibility issue definitely.
Changed to enhancement.
I just want to get my thoughts down about this issue before I forget them.
I think for our next major version we need to have a discussion around exactly how we store / save / retrieve data from the database. For example, as of today, we have save, update, and modify for writing to the database.
In my opinion it has become a little confusing for a user to know when to use what update method and exactly what impact it has on MongoEngine cached data.
We may contribute since we've spent quite some time understanding and working with the current mechanics in mongoengine-relational and tastymongo (names are not apt for current functionality).
@MacMaru Feel free to submit a pull request.
Not obvious behavior ..
I think update should work the way it does. Agreed that it might be confusing and unintuitive for people new to MongoEngine, but there's a good reason for it.
If we wanted update to reliably alter the attributes of a document, we'd have to either reload the object upon every update or use findAndModify (which is already covered by modify). It's also tempting to think that we'd be able to replicate all of the MongoDB operators in MongoEngine ($set, $unset, $inc, $pop, $push, $pullAll, and so on), but that would hugely complicate the codebase and at the same time it doesn't guarantee that our document is in sync with the database.
In my opinion, the fact that some people find update confusing is a documentation issue, not a behavior issue.
Why doesn't update have the same behavior as save?
Why doesn't update have the same behavior as save?
At least mention this unexpected behavior in the docs!
Why doesn't update have the same behavior as save?
I cannot believe that after 8 years and 3 months this issue is still valid.
Use modify instead