Modifying django to have a BlobField for storing binary data in mysql
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
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
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.
Use djangotoolbox instead. It has a BlobField
I didn’t exist a few years ago when I wrote this though.