kombu.exceptions.EncodeError: [‹Vkwallpost: объект Vkwallpost› не сериализуем JSON - только на локальном хосте

Я использую Django + Celery + Kombu + rabbitmq: моя задача успешно выполнена на сервере (Ubuntu 14.04)

[2016-01-21 02:29:05,027: INFO/MainProcess] Task vk_wall.tasks.get_wallposts_by_owner_id[cbdfbdf7-1f01-4cf1-bd5a-77fae7a07003] succeeded in 7.826467196922749s: [<Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost...

но на localhost (Windows 7) при тех же настройках выдает ошибку:

[2016-01-21 02:34:54,296: ERROR/MainProcess] Task vk_wall.tasks.get_wallposts_by_owner_id[5ecbf611-15d7-4b75-ac8e-2575b5dc869a] raised unexpected: EncodeError(TypeError(TypeError("[<Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, '...(remaining elements truncated)...'] is not JSON serializable",),),)
Traceback (most recent call last):
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\celery\app\trace.py", line 283, in trace_task
    uuid, retval, SUCCESS, request=task_request,
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\celery\backends\amqp.py", line 136, in store_result
    delivery_mode=self.delivery_mode,
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\messaging.py", line 165, in publish
    compression, headers)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\messaging.py", line 241, in _prepare
    body) = dumps(body, serializer=serializer)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\serialization.py", line 164, in dumps
    payload = encoder(data)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\contextlib.py", line 77, in __exit__
    self.gen.throw(type, value, traceback)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\serialization.py", line 59, in _reraise_errors
    reraise(wrapper, wrapper(exc), sys.exc_info()[2])
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\five.py", line 131, in reraise
    raise value.with_traceback(tb)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\serialization.py", line 55, in _reraise_errors
    yield
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\kombu\serialization.py", line 164, in dumps
    payload = encoder(data)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\anyjson\__init__.py", line 141, in dumps
    return implementation.dumps(value)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\anyjson\__init__.py", line 89, in dumps
    raise TypeError(TypeError(*exc.args)).with_traceback(sys.exc_info()[2])
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\anyjson\__init__.py", line 87, in dumps
    return self._encode(data)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\simplejson\__init__.py", line 370, in dumps
    return _default_encoder.encode(obj)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\simplejson\encoder.py", line 269, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\simplejson\encoder.py", line 348, in iterencode
    return _iterencode(o, 0)
  File "M:\WinPython-64bit-3.4.3.2\python-3.4.3.amd64\lib\site-packages\simplejson\encoder.py", line 246, in default
    raise TypeError(repr(o) + " is not JSON serializable")
kombu.exceptions.EncodeError: [<Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, <Vkwallpost: Vkwallpost object>, '...(remaining elements truncated)...'] is not JSON serializable

Итак, задача отмечена как незавершенная, но на самом деле задача делает все, что мне нужно. Я просмотрел ответы на похожие вопросы: моя задача возвращает dict i.e. {'success': success}. Кажется, что он пытается сериализовать объекты Vkwallpost, которые являются экземпляром модели Django, но почему.

мои настройки.py:

#BROKER_URL = 'amqp://guest:guest@localhost//'
BROKER_URL = 'django://'

#: Only add pickle to this list if your broker is secured
#: from unwanted access (see userguide/security.html)
CELERY_ACCEPT_CONTENT = ['json', 'pickle']
CELERY_TASK_RESULT_EXPIRES=3600
#CELERY_RESULT_BACKEND='amqp'
CELERY_RESULT_BACKEND='djcelery.backends.database:DatabaseBackend'
# postgresql
#CELERY_RESULT_BACKEND = 'db+postgresql://postgres:111222@localhost/graphgrail'
#CELERY_RESULT_BACKEND='djcelery.backends.cache:CacheBackend',
CELERY_RESULT_SERIALIZER = 'json' #json pickle msgpack
CELERY_TASK_SERIALIZER = 'json'
CELERY_IMPORTS=["vk_wall.tasks"]

person Vic Nicethemer    schedule 20.01.2016    source источник


Ответы (1)


Объекты не сериализуются в формате JSON. Если сериализация прошла успешно в Linux, это означает, что вы, вероятно, используете там метод сериализации pickle.

Я бы предложил использовать метод сериализации pickle в Windows, явно указав его с помощью одного из упомянутых методов здесь.

person scytale    schedule 21.01.2016
comment
Проблема в том, что если я заменю все json на рассол в настройках, он откажется обрабатывать задачу из-за безопасности - person Vic Nicethemer; 22.01.2016
comment
извините - это не имеет большого смысла. что вы имеете в виду из-за безопасности? Вы можете опубликовать сообщение об ошибке, если оно есть? - person scytale; 25.01.2016
comment
то же, что в этом вопросе stackoverflow.com/questions/27578235/ Предоставленное там решение мне не помогло - person Vic Nicethemer; 27.01.2016
comment
подождите - вы пытаетесь вернуть объекты python в своих результатах? это кажется плохой идеей - вы пытались реструктурировать свой код, чтобы вы не передавали объекты - это позволит вам использовать только json - person scytale; 27.01.2016
comment
нет, в обмен на мою задачу нет объектов python или django, простой dict. Я сохраняю модель django в этой задаче. Так что невозможно переписать код, я думаю, что правильное решение не в том, чтобы вручную взломать объект django для json - person Vic Nicethemer; 27.01.2016
comment
Я не понимаю, что вы имеете в виду, чтобы не вручную взломать объект django для json. где-то ваш код пытается передать объекты python в качестве результатов сельдерея - это то, что показывает трассировка в вашем исключении. вам, вероятно, не следует этого делать. - person scytale; 27.01.2016