0

I'm new to mongoengine. I am trying to get the pre_delete hook to delete a FileField storing in GridFS.

I am using Python 2.7.10, Mongo 3.4 and mongoengine 0.8.7.

Here is what I have.

import uuid

import mongoengine as me

class MyFiles(me.Document):
    meta = {"collection": "test"}
    guid = me.UUIDField(binary=False, required=True)
    my_file = me.FileField()

    @classmethod
    def pre_delete(cls, sender, document, **kwargs):
        document.my_file.delete()


if __name__ == '__main__':
    me.connect(db='main', alias='default', host='localhost')

    m = MyFiles(guid=uuid.uuid4())
    m.my_file.new_file(content_type='text/plain')
    m.my_file.write("This is")
    m.my_file.write("my file")
    m.my_file.write("Hooray!")
    m.my_file.close()
    m.save()

    print(m.my_file.read())

    m.delete()

Now I am debugging with a breakpoint on m.delete()

my.file.read() worked.

enter image description here There is a document in collection "test" that refers to the file in GridFS. enter image description here

There is a file in fs.files. enter image description here

And in fs.chunks. enter image description here

Now I ran m.delete(). Collection "test" is empty. enter image description here

fs.files is not empty. Neither is fs.chunks. The file remains. enter image description here

According to mongoengine docs for gridfs, I need to run m.my_file.delete() to delete the GridFS entry before deleting the MyFiles document. I have confirmed this works if I put m.my_file.delete() before m.delete() like so.

m.save()

print(m.my_file.read())

m.my_file.delete()
m.delete()

However I want it to run in pre_delete. This seems like the purpose of pre_delete. Any ideas what I am doing wrong?

Daniel
  • 542
  • 1
  • 4
  • 19

1 Answers1

0

Here is the problem. I did not register the signal. This works:

import uuid

import mongoengine as me

class MyFiles(me.Document):
    meta = {"collection": "test"}
    guid = me.UUIDField(binary=False, required=True)
    my_file = me.FileField()

    @classmethod
    def pre_delete(cls, sender, document, **kwargs):
        document.my_file.delete()

me.signals.pre_delete.connect(MyFiles.pre_delete, sender=MyFiles)


if __name__ == '__main__':
    me.connect(db='main', alias='default', host='localhost')

    m = MyFiles(guid=uuid.uuid4())
    m.my_file.new_file(content_type='text/plain')
    m.my_file.write("This is")
    m.my_file.write("my file")
    m.my_file.write("Hooray!")
    m.my_file.close()
    m.save()

    print(m.my_file.read())

    m.delete()
Daniel
  • 542
  • 1
  • 4
  • 19