Mongoengine: Document.save not saving the doc

Created on 2 Mar 2016  Â·  3Comments  Â·  Source: MongoEngine/mongoengine

Storing an instance with only primary_key set doesn't store the document. If any other field is set apart from primary_key the document is getting stored.

This must be happening as mongoengine assuming it to be update and as the instance has no other data set, hence mongoengine is getting northing in updates and removals.

Eg:

class Sample(Document):
    key = StringField(primary_key=True)
    count = IntField()

sample = Sample()
sample.key = "123"
sample.save() # does nothing

sample.count = 0
sample.save() # saves the document

I know I can use force_insert in save to make it work. but is this the desired behaviour?

Discussion

Most helpful comment

MongoDB allows for compound primary keys. Store an embedded document. There are very specific concerns relating to ensuring the order of the nested values is consistent between documents (or you lose out on sane ordering and range querying), and exact matching on the _id field requiring a fully populated sub-document, but. Two fields marked primary_key is entirely reasonable. One of our analytics collections, as an example, has an 8 way primary key. (Time-sliced unique combination of company, invoice, job, site, user, and package…)

On the actual issue of this ticket: if any ID is present, MongoEngine has no way of knowing (without performing additional, potentially expensive queries) that the document is actually new and not present in the DB. force_insert is required in this situation, since "save" has multiple meanings. One of the reasons I'm slowly migrating away from this style of "active record"… the ambiguities and edge cases just make things confusing and complicated. (The bare PyMongo driver does not suffer this problem, with a clear separation between .update_one/many and .insert_one/many.)

All 3 comments

primary_key functionality must be revised.
mongodb has "_id" as a primary key. https://docs.mongodb.org/manual/core/index-single/#index-type-id
Thus, db_field parameter (which is default to the name of the field) is invalid in context when primary_key is True.

Also, keys may be compound, and if having two fields with primary_key in the same document, should it be considered as a compound key or invalid document definition?

Clarifications are necessary to proceed.

MongoDB allows for compound primary keys. Store an embedded document. There are very specific concerns relating to ensuring the order of the nested values is consistent between documents (or you lose out on sane ordering and range querying), and exact matching on the _id field requiring a fully populated sub-document, but. Two fields marked primary_key is entirely reasonable. One of our analytics collections, as an example, has an 8 way primary key. (Time-sliced unique combination of company, invoice, job, site, user, and package…)

On the actual issue of this ticket: if any ID is present, MongoEngine has no way of knowing (without performing additional, potentially expensive queries) that the document is actually new and not present in the DB. force_insert is required in this situation, since "save" has multiple meanings. One of the reasons I'm slowly migrating away from this style of "active record"… the ambiguities and edge cases just make things confusing and complicated. (The bare PyMongo driver does not suffer this problem, with a clear separation between .update_one/many and .insert_one/many.)

Agreed with everything @amcgregor said.

There's not much we can do here given that we don't know whether a document with a given ID already exists or not. Please use QuerySet.objects.insert(doc) or doc.save(force_insert=True).

Was this page helpful?
0 / 5 - 0 ratings