Home > Programming & scripting, Python > Modifying django to have a BlobField for storing binary data in mysql

Modifying django to have a BlobField for storing binary data in mysql

July 25th, 2007

Like I mentioned in my last post I’ve been playing around a bit with XBT Tracker which uses a blob-field for storing a binary hash.

I want to build a site arround this using django, but for some reason there are no BlogField available in the model-api, so I had to make my own, and am posting how to do it here if anyone else is interested and also to keep a not to myself of how I did it for later use (there are no BigInteger in django either I belive so that’s next).

I chose to ignore portability for this, since I only use mysql and have zero experience with the other databases and this was just a fix for my own site really. Hopefully django will get a BigIntegerField and BlobField in the release eventually.

Anyways… to start adding the BlobField, open the file “creation.py” in the django/db/backends/mysql folder. In my case

/usr/lib/python2.4/site-packages/django/db/backends/mysql/creation.py

In the list of DATA_TYPES, add

'BlobField':         'blob',

Then open the file “introspection.py” in the same folder. In my case

/usr/lib/python2.4/site-packages/django/db/backends/mysql/introspection.py

Change

FIELD_TYPE.BLOB: 'TextField',

to

FIELD_TYPE.BLOB: 'BlobField',

Then finally open __init__.py in django/db/models/fields . In my case

/usr/lib/python2.4/site-packages/django/db/models/fields/__init__.py

Then simply copy TextFields class, put it below the TextField class and rename the copy BlobField
It should look something like this:

class BlobField(Field):
    def get_manipulator_field_objs(self):
        return [oldforms.LargeTextField]

    def formfield(self, **kwargs):
        defaults = {'required': not self.blank, 'widget': forms.Textarea,
                   'label': capfirst(self.verbose_name), 'help_text': self.help_text}
        defaults.update(kwargs)
        return forms.CharField(**defaults)

This should make the admin panel use the same widgets and so on as the TextArea which hopefully should be fine. You probably wont use the admin-panel for a BlobField anyways :)
There might be some issues with this, since TextField uses some validators that you dont want here, but like I said… the chances that you will insert binary data through the admin interface is rather low. Feel free to drop me a comment if this part does not work.

Finally you might want to remove all compiled pythonfiles (.pyc) since they wont be updated. Unsure if this is needed, but… well I did it and it worked for me :P

buffi@jenet:~$ cd /usr/lib/python2.4/site-packages/django/ #path to your django install
buffi@jenet:/usr/lib/python2.4/site-packages/django$ find ./ -name "*.pyc" -print | xargs rm

Ok… time to try out making a model with it.

Sample model:

from django.db import models

class MyModel(models.Model):
    my_field = models.BlobField()

And then let’s test it…

buffi@jenet:~/site/testblob$ python manage.py validate
0 errors found.
buffi@jenet:~/site/testblob$ python manage.py sqlall testapp
BEGIN;
CREATE TABLE `testapp_mymodel` (
    `id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY,
    `my_field` blob NOT NULL
);
COMMIT;

Looks good!
Doing a

python manage.py syncdb

works just fine as well. Then it’s just actually using it left…

$ python manage.py shell
Python 2.4.4 (#2, Apr  5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from myapp import models
>>> binary_stuff = '\x00\x01\x02'
>>> m = models.MyModel(my_field=binary_stuff)
>>> m.save()
>>>

Whoaa, it works!
Checking the mysql database confirms that it works…

So yeah, it’s not platform independent or anything but if you want to use blob fields in mysql then this might be for you ;)

buffi Programming & scripting, Python

  1. March 15th, 2008 at 18:11 | #1

    I’m pretty sure you will have problems with this in Django since the ‘unicodization’ took place. This is because text fields no longer store bytestrings (which is what you want for binary data) but unicode strings. Django expects all input to be UTF-8, so if you happen to edit one of these objects in the admin, you won’t be able to save it, since the data won’t be valid UTF-8. It’s possible there will be problems at other points too, I’m not sure.

  2. June 14th, 2010 at 19:46 | #2

    Use djangotoolbox instead. It has a BlobField

  3. August 7th, 2010 at 19:21 | #3

    I didn’t exist a few years ago when I wrote this though.

  1. No trackbacks yet.