在MySQL数据库中保存Python Pickled对象

11

我正在Django中将Python对象进行pickling并保存在MySQL数据库中。到目前为止,我已经遵循了以下简单的规则:

  1. cPickle.dumps(object) # 将Python对象转换为pickled对象

  2. cPickle.loads(pickled_object) # 从pickled对象加载回Python对象

  3. 我的Django Model FieldTextField

  4. MySQL数据库字段类型是longblob,属性是binary

  5. MySQL数据库编码是utf8_unicode_ci

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

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

通过观察错误值x07xb6x0bx06,我认为这是一个编码问题。我错过了重要的步骤吗?有人能帮我解决这个问题吗?


1
你使用pickle有特定的原因吗?它是一种二进制格式,只能被Python使用。如果可以选择,JSON不是更好的选项吗? - Noufal Ibrahim
JSON不符合我的需求,我尝试使用json.dumps但是出现了错误some_object is not JSON serializable。而且这个对象是纯Python的。 - Aamir Rind
2
你应该尝试将那个对象也序列化。当你试图查找错误时,在数据库中拥有可读性的内容是非常有帮助的。 - Noufal Ibrahim
4个回答

7
如果你想将的输出存储在列中,那么你的问题是你试图将一个字节字符串存储在字符列中。在这种情况下的解决方法是将对象编码为,然后再存储它。
或者:
object2varchar = lambda obj: unicode(base64.encode(cPickle.dumps(obj)))
store(object2varchar([1, 'foo']))

1

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

更新1: 有时候查看完整的SQL查询是个好主意,我通常就是这么做的:

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

@aamir-adnan,你尝试过保存和读取新项目而不是读取已保存的项目吗? - newtover
好问题,是的我检查过了,在代码中转换和恢复Python对象时它能正常工作,但在读取或存储不正确的情况下会出现问题。我该怎么办?请帮忙。 - Aamir Rind
@aamir-adhan,我的意思是之前的项目可能保存在错误的编码中,现在可以正确地读取。 - newtover
不使用Django Model(与Django Models的“Text field”与MySQL的“blob field”的行为混淆),我直接连接到数据库并将pickled对象直接存储在数据库中。但是,仍然出现相同的错误 :-( - Aamir Rind
是的,我总是更新字段然后读取新值。我不会读取旧保存的值。 - Aamir Rind

0

0

现在你可以尝试这个! 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()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接