2013-03-18 42 views
2

首先的存儲BLOB數據,我知道有很多這樣類似的問題,但其他的解決方案不包括我的具體情況:使用Django和sqlite的

在我的SQLite數據庫是現有的二進制數據(SHA1和類似的哈希)。隨着谷歌搜索和閱讀django-docs我想出了以下內容:

import base64 

class BlobField(models.Field): 
""" 
Stores raw binary data 
""" 

description = 'Stores raw binary data' 
__metaclass__ = models.SubfieldBase 

def __init__(self, *args, **kwds): 
    super(BlobField, self).__init__(*args, **kwds) 

def get_internal_type(self): 
    return "BlobField" 

def get_db_prep_value(self, value, connection=None, prepared=False): 
    return base64.decodestring(value) 

def to_python(self, value): 
    return base64.encodestring(value) 

這我想要做什麼,該值編碼,並在適當的時候進行解碼,但在模型保存到數據庫中它給了我下面的錯誤:

DatabaseError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

我該如何解決這個問題? (可能沒有打破在應用程序的其餘全部我的Unicode的兼容性)

因爲數據是由另一個應用程序我不能改變的DB-列的格式。


編輯: 如所建議的通過@菲利普-dupanovic,我採用了BinaryField類,如下所示:

類BinaryField(models.Field): 描述= _( 「原始二進制數據」)

def __init__(self, *args, **kwargs): 
    kwargs['editable'] = False 
    super(BinaryField, self).__init__(*args, **kwargs) 
    if self.max_length is not None: 
     self.validators.append(validators.MaxLengthValidator(self.max_length)) 

def get_internal_type(self): 
    return "BinaryField" 

def get_default(self): 
    if self.has_default() and not callable(self.default): 
     return self.default 
    default = super(BinaryField, self).get_default() 
    if default == '': 
     return b'' 
    return default 

def get_db_prep_value(self, value, connection, prepared=False): 
    #value = super(BinaryField, self 
    # ).get_db_prep_value(value, prepared, connection=connection) 
    #if value is not None: 
    # return connection.Database.Binary(value) 
    return value 

通知我在get_db_prep_value()插入,這樣的評論,它按預期工作,如果我取消註釋行我得到一個錯誤

TypeError: get_db_prep_value() got multiple values for keyword argument 'connection'

我可以這樣生活,但不完全瞭解留下它的含義。將它仍然正常工作,甚至沒有調用super()

+0

這就是我第一次嘗試,但它沒有工作。我很滿足於目前的解決方案,如圖我的編輯,如果沒有一個張貼關於我加入,我會堅持下去的評論有任何疑問 – tannerli 2013-03-19 09:59:05

回答

1

票務#2417,收盤前不久,加入了BinaryField模型字段。你應該看看this commit,具體涉及到如何在你的內部BlobField字段類型映射到你的數據庫支持的適當類型的變化。

0
def get_db_prep_value(self, value, connection, prepared=False): 
    value = super(BinaryField, self 
     ).get_db_prep_value(value, connection, prepared) 
    if value is not None: 
     return connection.Database.Binary(value) 
    return value 
+0

那麼你所做的是改變調用'BinaryField.get_db_prep_value的參數的順序',這需要仔細閱讀。 – Anthon 2013-03-19 10:33:22