存储pickle'd数据时出现DjangoUnicodeDecodeError

时间:2010-03-26 16:36:52

标签: django unicode pickle

我有一个简单的dict对象,我试图在运行pickle后将其存储在数据库中。似乎Django不喜欢尝试编码此错误。我已经检查过MySQL,并且在它抛出错误之前查询甚至没有到达那里,所以我不相信这是问题所在。我存储的dict看起来像这样:

{
    'ordered': [
        {   'value': u'First\xd1ame Last\xd1ame',
            'label': u'Full Name' },
        {   'value': u'123-456-7890',
            'label': u'Phone Number' },
        {   'value': u'user@nowhere.org',
            'label': u'Email Address' } ],
    'cleaned_data': {
        u'Phone Number': u'123-456-7890',
        u'Full Name': u'First\xd1ame Last\xd1ame',
        u'Email Address': u'user@nowhere.org' },
    'post_data': <QueryDict: {
        u'Phone Number': [u'1234567890'],
        u'Full Name_1': [u'Last\xd1ame'],
        u'Full Name_0': [u'First\xd1ame'],
        u'Email Address': [u'user@nowhere.org'] }>,
    'user': <User: itis>
}

抛出的错误是:

  

'utf8'编解码器无法解码位置52-53中的字节:无效数据。

位置52-53是pickle数据中\xd1(Ñ)的第一个实例。

到目前为止,我已经在StackOverflow周围挖了几个问题,其中对象的数据库编码是错误的。这对我没有帮助,因为还没有MySQL查询。这发生在数据库之前。在搜索腌制数据的unicode错误时,谷歌也没有多大帮助。

值得一提的是,如果我不使用Ñ,这段代码就可以了。

3 个答案:

答案 0 :(得分:3)

非常感谢@prometheus,我找到了解决方案。基本上,您可以使用base64对pickle.dumps()的输出进行编码,然后再将其插入数据库。然后,您将转向并使用base64解码数据库的输出,然后再将其传递给pickle.loads()

我的代码现在看起来像这样:

## Put the information into the database:
self.raw_data = base64.b64encode(pickle.dumps(data))

## Get the information out of the database:
return pickle.loads(base64.b64decode(self.raw_data))

再次感谢@prometheus。

答案 1 :(得分:2)

这是一个已知问题,并在Python bug-tracker上讨论了这个问题:

  

今天我在将python数据结构写入a时遇到了这个问题   数据库。在这种情况下,只有ASCII是安全的。我理解了   Python文档,协议0只是ASCII。

     

我现在使用pickle + base64,但这会使调试变得更加困难。

     

无论如何,我认为文档应该清楚地说协议0不是   仅限ASCII,因为这在Python世界中很重要。例如,   我看到了这个问题,因为Django进行了隐式的unicode()转换   我的输入因非ASCII而失败。

答案 2 :(得分:1)

我认为没有必要这样做。通常,应该可以将任何二进制数据存储在数据库中。

更糟糕的问题是酸洗不安全 - 如果数据库可以从任何地方获取数据,它可能会得到恶意的酸洗数据。