4

前もって感謝します :)

私はこの非同期Celeryタスクコールを持っています:

update_solr.delay(id, context)

ここで、id は整数で、context は Python dict です。

私のタスク定義は次のようになります。

@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)

ここclip_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修正するために、非同期呼び出しの前に に依存するコードを実行し、ネイティブ タイプのみの dict を渡しました。

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 に答える