Question

In MongoEngine, when deleting an EmbeddedDocument from a ListField which includes a FileField, the referenced file does not get deleted. Currently, I have solved the issue by looping over the whole list field.

for embdoc in doc.embdocs:
    if embdoc.filtered == value:
        embdoc.dfile.delete()
doc.update(pull__embdocs={'filtered': value})

I was wondering if there was a better way to do this.

Was it helpful?

Solution

By default, MongoDB doesn’t check the integrity of your data, so deleting documents that other documents still hold references to will lead to consistency issues.

You should use ListField with ReferenceFields. ReferenceFields can used with option reverse_delete_rule=mongoengine.PULL or another:

mongoengine.DO_NOTHING This is the default and won’t do anything. Deletes are fast, but may cause database inconsistency or dangling references.

mongoengine.DENY Deletion is denied if there still exist references to the object being deleted.

mongoengine.NULLIFY Any object’s fields still referring to the object being deleted are removed (using MongoDB’s “unset” operation), effectively nullifying the relationship.

mongoengine.CASCADE Any object containing fields that are refererring to the object being deleted are deleted first.

mongoengine.PULL Removes the reference to the object (using MongoDB’s “pull” operation) from any object’s fields of ListField (ReferenceField).

OTHER TIPS

I also was in need to delete a file in a list field inside an embedded document, after a lot of searches I came across this soultion

the Document:

class AllTheFiles(me.EmbeddedDocument):
    type1 = me.ListField(me.FileField())
    type2 = me.ListField(me.FileField())

class MainDocument(me.Document):
    files = me.EmbeddedDocumentField(AllTheFiles)

I am assuming here that you have some documents and they have files, in the real world you will need to check if there are files and for documents existns.

So in order to delete the first file(index 0) in the type1 field:

del_here = MainDocument.objects()[0]

del_here.files.type1[0].delete()
del_here.files.type1.pop(0)
del_here.save()

The file will be deleted in the embedded document type1 list and also in "fs.files" and "fs.chuncks" colloctions.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top