我有一个简单的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错误时,谷歌也没有多大帮助。
值得一提的是,如果我不使用Ñ,这段代码就可以了。
答案 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)
我认为没有必要这样做。通常,应该可以将任何二进制数据存储在数据库中。
更糟糕的问题是酸洗不安全 - 如果数据库可以从任何地方获取数据,它可能会得到恶意的酸洗数据。