ZODB, how to properly delete a BLOB file
Due one of my Pyramid current projects, I was playing a bit with ZODB and blob image storing. After reading here and there, I had no idea how to properly delete a filesystem stored image, blob field related. I though best way was to use remove_committed() ZODB.blob method with something like:
def delete_avatar(): image = myobj.avatar if isinstance(image, Blob): remove_committed(image.committed()) myobj.avatar = None
But after talking a bit with skilled ZODB people, they said that updating the database value and packing the database was enough to clear all the references in filesystem. First time ever I read something about "packing" a ZODB, so I had to probe it by myself.
pshell$ profile.avatar (ZODB.blob.Blob object at 0x108167230)
Once we reached the image we can get it's path and some other interesting data for this test from pshell
and shell:
pshell$ profile.avatar.committed() '/path/to/myproject/var/blobstorage/0x00/0x00/0x00/0x00/0x00/0x02/0xbd/0x68/0x03ab15928a1fb511.blob'
$ ls /path/to/myproject/var/blobstorage/0x00/0x00/0x00/0x00/0x00/0x02/0xbd/0x68/0x03ab15928a1fb511.blob /0x03ab15928a1fb511.blob $ find . -name *.blob | wc -l 12 $ du -s . 4784 .
Nice!, if I open the .blob
file with whatever image editor I get the proper image, next step is to enter in pshell
mode again, update the database code to None
,commit the transaction and see what's happening in the filesystem:
pshell$ profile.avatar = None pshell$ profile.avatar pshell$ import transaction pshell$ transaction.commit()
$ find . -name *.blob | wc -l 12 $ du -s . 4784 .
Nothing seems to be happened, after the commit, find
and du
are showing the same information as before, last step is to pack
the database...
pshell$ from pyramid_zodbconn import get_connection pshell$ conn = get_connection(request) pshell$ conn.db().pack()
$ find . -name *.blob | wc -l 11 $ du -s . 4504 . $ ls /path/to/myproject/var/blobstorage/0x00/0x00/0x00/0x00/0x00/0x02/0xbd/0x68/0x03ab15928a1fb511.blob $
That's it!, after a couple of seconds "packing", the filesystem seems to be updated, the file was properly deleted and all the information seems to be in a right state.
In the end seems that the remove_commited() function was not the right way to delete a BLOB file from ZODB, thumbs up for the packing!.