Сохранение Python Pickled объектов в БД MySQL - PullRequest
9 голосов
/ 16 ноября 2011

Я выбираю объекты Python в Django и сохраняю их в базе данных MySQL.До сих пор я следовал этим простым правилам:

  1. cPickle.dumps(object) # для преобразования объекта python в засоленный объект

  2. cPickle.loads(pickled_object) # для загрузкивернуть объект python из засоленного объекта

  3. Мой Django Model Field равен Text Field

  4. MySQL db field Тип: longblob Атрибуты binary

  5. Кодировка базы данных MySQL равна utf8_unicode_ci

К сожалению, я получаю следующую ошибку при загрузке объекта Python назад.

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

Мне кажется, глядя на значение ошибки x07xb6x0bx06, это проблема кодирования.Я пропустил какой-то важный шаг?Может ли кто-нибудь помочь мне решить эту проблему ??

Ответы [ 4 ]

6 голосов
/ 16 ноября 2011

Если вы пытаетесь сохранить выходные данные cPickle.dumps в столбце VARCHAR, то ваша проблема заключается в том, что вы пытаетесь сохранить байтовую строку в символьном столбце. Исправление в этом случае заключается в том, чтобы закодировать ваш объект как unicode(base64.encode(cPickle.dumps(myobject))) и затем сохранить его.

В качестве альтернативы:

object2varchar = lambda obj: unicode(base64.encode(cPickle.dumps(obj)))
store(object2varchar([1, 'foo']))
1 голос
/ 16 ноября 2011

еще одно правило: подключайтесь к mysql с параметром charset=utf8?

UPD1: Иногда полезно посмотреть полный SQL-запрос, обычно я делаю это так:

>>> conn = MySQLdb.connect(**db_params)
>>> "INSERT INTO tbl VALUES (%s)" % conn.literal((your_pickled_item, ))
0 голосов
/ 15 мая 2019

Вы можете попробовать это сейчас!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()
0 голосов
/ 16 ноября 2011

Ответ Newtover, вероятно, правильный, но взгляните на

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

Это действительно сэкономило мне время и может хранить практически все, что вы хотите.

...