4

提前致谢 :)

我有这个异步芹菜任务调用:

update_solr.delay(id, context)

其中 id 是一个整数,context 是一个 Python 字典。

我的任务定义如下:

@task
def update_solr(id, context):
    clip = Clip.objects.get(pk=id)
    clip_serializer = SOLRClipSerializer(clip, context=context)
    response = requests.post(url, data=clip_serializer.data)

whereclip_serializer.data是一个 dict 并且url是一个表示 url 的字符串。

当我尝试调用update_solr.delay()时,我收到此错误:

PicklingError: Can't pickle <type 'instancemethod'>: attribute lookup __builtin__.instancemethod failed

任务的两个参数都不是实例方法,所以我很困惑。

当任务代码同步运行时,没有错误。

更新:修复了关于传递 pk 而不是对象的评论。

4

3 回答 3

5

context字典中有一个对象,我不知道......

为了解决这个问题,我执行了依赖于context异步调用之前的代码,并且只传递了一个只有本机类型的字典:

def post_save(self, obj, created=False):
    context = self.get_serializer_context()
    clip_serializer = SolrClipSerializer(obj, context=context)
    update_solr.delay(clip_serializer.data)

任务最终是这样的:

@task
def update_solr(data):
    response = requests.post(url, data=data)

这非常好,因为使它成为异步任务的唯一目的是使 POST 非阻塞。

谢谢您的帮助!

于 2013-08-15T06:04:28.683 回答
1

尝试传递模型实例主键 ( pk)。这更容易腌制,减少有效负载并避免竞争条件。

于 2013-08-15T05:53:07.650 回答
0
import pickle
class X:
    def y(self):
        pass

pickle.dumps(X.y)

Pickle 以递归方式工作,因此它可能位于对象图中的任何位置。您得到了解决方案 - 仅传输最小对象,即主键等,而不是 Django 模型对象。

于 2013-08-15T05:41:33.453 回答