4

我有一个简单的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 中的字节:无效数据。

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

到目前为止,我已经在 StackOverflow 上进行了研究,发现了一些问题,其中对象的数据库编码是错误的。这对我没有帮助,因为还没有 MySQL 查询。这发生在数据库之前。在搜索腌制数据的 unicode 错误时,Google 也没有太大帮助。

可能值得一提的是,如果我不使用 Ñ,这段代码可以正常工作。

4

3 回答 3

5

非常感谢@prometheus,我找到了解决方案。基本上,您可以在将输出pickle.dumps()插入数据库之前使用 base64 对其进行编码。然后,您将转身使用 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。

于 2010-03-29T17:01:46.997 回答
2

这是一个已知问题,在Python bug-tracker上对此进行了讨论:

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

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

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

于 2010-03-26T22:30:06.357 回答
1

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

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

于 2011-07-27T19:30:12.643 回答