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!.