【问题标题】:Saving Python Pickled objects in MySQL db在 MySQL 数据库中保存 Python Pickled 对象
【发布时间】:2011-12-30 07:23:26
【问题描述】:

我在 Django 中腌制 Python 对象并将其保存在 MySQL 数据库中。 到目前为止,我遵循了这些简单的规则:

  1. cPickle.dumps(object) #将python对象转换为腌制对象

  2. cPickle.loads(pickled_object) #从腌制对象中加载回python对象

  3. 我的 Django Model FieldText Field

  4. MySQL db 字段类型为longblob 属性binary

  5. MySQL db 编码为utf8_unicode_ci

不幸的是,我在加载回 python 对象时遇到以下错误。

Type Error: ('an integer is required', <type 'datetime.date'>, ('x07xb6x0bx06',))

在我看来,通过查看错误值x07xb6x0bx06 这是一个编码问题。 我错过了一些重要的步骤吗?谁能帮我解决这个问题??

【问题讨论】:

  • 你有使用泡菜的具体原因吗?这是一种二进制格式,只能由 python 使用。如果可以选择,JSON 不是更好的选择吗?
  • JSON 不符合我的目的,我尝试使用json.dumps,但收到此错误some_object is not JSON serializable。而且对象是纯 Pythonic。
  • 您应该尝试使该对象也可序列化。当您尝试查找错误时,在您的数据库中包含人类可读的内容是一个帮助。

标签: python mysql django pickle


【解决方案1】:

如果您尝试将cPickle.dumps 的输出存储在VARCHAR 列中,那么您的问题是您尝试将字节字符串存储在字符列中。在这种情况下,解决方法是将您的对象编码为unicode(base64.encode(cPickle.dumps(myobject))),然后将其存储。

或者:

object2varchar = lambda obj: unicode(base64.encode(cPickle.dumps(obj)))
store(object2varchar([1, 'foo']))

【讨论】:

    【解决方案2】:

    还有一条规则:使用选项charset=utf8连接到mysql?

    UPD1: 有时查看完整的 SQL 查询是个好主意,我通常这样做:

    >>> conn = MySQLdb.connect(**db_params)
    >>> "INSERT INTO tbl VALUES (%s)" % conn.literal((your_pickled_item, ))
    

    【讨论】:

    • @aamir-adnan,您是否尝试过保存并阅读新项目而不是阅读已保存的内容?
    • 好问题,是的,我检查了它,当我在代码中转换和恢复 python 对象时它工作正常,读取或不正确存储时 db 有问题。我该怎么办?请帮忙。
    • @aamir-adhan,我的意思是以前的项目可能以错误的编码保存,现在可以正确读取 noew。
    • 而不是使用 Django 模型(混淆了 Django 模型 Text field 和 MySQL blob field 的行为),我 directly 连接到 db 并将腌制对象直接存储在 db 中。但同样的错误:-(
    • 是的,我总是更新字段,然后读取新值。我没有读取旧的保存值。
    【解决方案3】:

    Newtover 的答案可能是正确的,但请看一下

    https://github.com/bradjasper/django-pickledfield

    它确实为我节省了一些时间,并且可以存储几乎任何你想要的东西。

    【讨论】:

      【解决方案4】:

      你可以试试这个,现在! django-picklefield https://pypi.org/project/django-picklefield/

      要使用,只需在模型中定义一个字段:

      >>> from picklefield.fields import PickledObjectField
      ... class SomeObject(models.Model):
      ...     args = PickledObjectField()
      

      并将您喜欢的任何内容(只要它是可腌制的)分配给该字段:

      >>> obj = SomeObject()
      >>> obj.args = ['fancy', {'objects': 'inside'}]
      >>> obj.save()
      

      【讨论】:

        猜你喜欢
        • 2018-12-07
        • 2018-03-12
        • 2021-11-01
        • 2016-11-21
        • 2016-08-01
        • 2018-05-30
        • 2021-11-06
        • 2018-02-25
        • 2019-09-15
        相关资源
        最近更新 更多