Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly format a StringIO object(python and django) to be inserted into an database?

I have a requeriment to store images in the database using django, and for that I created a custom field :

from django.db import models

class BlobField(models.Field):

    __metaclass__ = models.SubfieldBase

    def db_type(self, connection):
        #TODO handle other db engines
        backend = connection.settings_dict['ENGINE']
        if backend == 'django.db.backends.postgresql':
            return 'bytea'
        elif backend == 'django.db.backends.sqlite3':
            return 'blob'
        else:
            raise Exception('unsuported db')

    def to_python(self, value):
        #TODO
        return value

    def get_db_prep_value(self, value, connection, prepared=False):
        #TODO              
        return value

I have already implemented a custom storage system to handle the storage/retrieval of images using a custom Model(that contains the above BlobField). The 'value' parameter in the 'get_db_prep_value' method is a 'StringIO' object that contains the image binary data. The catch is that I don't know what to return in the 'get_db_prep_value' method since the 'StringIO' object will surely contain non-printable characters.

I have some questions about the problem:

  • What should I return in the 'get_db_prep_value' method?
  • If the expected value is an ASCII string, can I represent the blob(hexadecimal escapes) in a database independent way?
  • If not, are there built in libraries that handle this kind of conversion for me?
  • What can I expect to receive as input for the 'to_python' method, and how can I convert it to a StringIO object?
like image 538
Thiago Padilha Avatar asked Dec 13 '22 19:12

Thiago Padilha


1 Answers

There is no constraint requiring get_db_prep_value to return "printable" characters, or ASCII ones, or otherwise-constrained sets of characters: return any byte string that catches your fancy. You'll get a string in to_python and can make a file-like StringIO instance reading its data with the_instance = StringIO.StringIO(value) (of course you'll need to import StringIO at the top of your module).

like image 83
Alex Martelli Avatar answered May 13 '23 16:05

Alex Martelli