Mongoengine: cascade_save does not save new referenced document

Created on 18 Feb 2016  路  11Comments  路  Source: MongoEngine/mongoengine

When saving a document with a ReferenceField holding a new object, I get an error:

mongoengine.errors.ValidationError: ValidationError 
You can only reference documents once they have been saved to the database

I naively expected cascade=True to automatically save the new document, while apparently it only automatically saves changes to existing documents.

Is this something that could be changed or is it meant to be for good reasons?

Example:

    class User(Document):
        name = StringField()

    class UserSubscription(Document):
        name = StringField()
        user = ReferenceField(User, dbref=False)

    User.drop_collection()
    UserSubscription.drop_collection()

    # u1 = User(name="Ross").save()
    u1 = User(name="Ross")

    sub = UserSubscription(user=u1).save()

I'd like this not to throw ValidationError but to save u1 in cascade.

Enhancement

Most helpful comment

Hi. Any news on this ? It seems like the bug is still there.

All 11 comments

I have the same problem. doc.save(cascade=True) does not save any documents unless they already exist, and doc.cascade_save() does not save the document itself.

Hi. Any news on this ? It seems like the bug is still there.

Get the same behaviour here with MongoEngine 0.11.0.

  • save(cascade=True) doesn't actually seem to do cascade saving (still gives the same errors as without cascade=True)
  • save_cascade() does not save the document itself

I have the same problem reported here, save(cascade=True) doesn't work and thus saving the parent document throws a ValidationError.

Same issue here.

+1 bumping this, it would be great to be able to save new embedded documents as references without having to dig into the substructure of the parent document to save all the new objects.

+1 bumping this. How is this still open after four years?

+1

+1 once again. Having to override the save method on all my classes is a massive PITA. Here's the method that I usually use if anyone wants it. Replace self.refs with your ReferenceFields.

def save(self, *args, **kwargs):
    for ref in self.refs.values():
        ref.save()
    return super().save(*args, **kwargs)

+1

+1

Was this page helpful?
0 / 5 - 0 ratings