代码之家  ›  专栏  ›  技术社区  ›  Jack M.

存储pickle数据时发生djangooncodeecodeerror错误

  •  3
  • Jack M.  · 技术社区  · 14 年前

    我有一个简单的 dict 对象运行后,我正尝试将其存储在数据库中 pickle . Django似乎不喜欢对这个错误进行编码。我已经用mysql检查过了,查询甚至在抛出错误之前都没有到达那里,所以我不认为这是问题所在。这个 双关语 我储存的东西是这样的:

    {
        '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是 \xd1 (_)在腌制数据中。

    到目前为止,我在stackoverflow周围进行了深入研究,发现了一些问题:对象的数据库编码哪里出错了。这对我没有帮助,因为还没有mysql查询。这发生在数据库之前。google在搜索pickled数据上的unicode错误时也没有太大帮助。

    可能值得一提的是,如果不使用,则此代码可以正常工作。

    3 回复  |  直到 13 年前
        1
  •  3
  •   Jack M.    14 年前

    多亏了“普罗米修斯”,我找到了解决办法。基本上,您可以使用base64对 pickle.dumps() 在把它插入数据库之前。然后,在将数据库的输出传递给 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))
    

    再次感谢你“普罗米修斯”。

        2
  •  2
  •   nikola    14 年前

    这是一个已知的问题,在 Python bug-tracker :

    今天在将python数据结构写入 数据库。在这种情况下,只有ascii是安全的。我明白了 python文档表明,协议0仅是ascii。

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

    不管怎样,我认为文档应该清楚地说明协议0不是 ascii只是因为这在python世界中很重要。例如, 我看到这个问题是因为django进行了隐式unicode()转换 使用非ascii失败的输入。

        3
  •  1
  •   glglgl    13 年前

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

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