代码之家  ›  专栏  ›  技术社区  ›  Sifnos

是否可以将ordereddict作为芹菜任务参数传递?

  •  0
  • Sifnos  · 技术社区  · 7 年前

    我在django rest框架的序列化器中 被推翻的 update 方法 .
    在这 更新 ,因为用户可以发送很多孩子,所以 异步芹菜任务 process_children ,来对付孩子们。

    class MyModelSerializer(serializers.ModelSerializer):
        ....
    
        @transaction.atomic
        def update(self, mymodel, validated_data):
            try:
                children_data = validated_data.pop('children')
                transaction.on_commit(lambda: process_children.apply_async(
                    countdown=1,
                    args=[mymodel.id, children_data]))
            except KeyError:
                pass
            ...
    

    在参数中,有一个参数 不是一个 json 对象,但 OrderedDict : children_data .

    任务看起来像:

    @app.task
    def process_children(mymodel_id, children_data):
        mymodel = MyModel.objects.get(pk=mymodel_id)
        children = mymodel.children.all()
        for child_data in children_data:
            try:
                child = children.get(start=child_data['start'])
                child = populate_child(child, child_data)
                child.save()
            except Child.DoesNotExist:
                create_child(mymodel, child_data)
    

    我听说我们应该 杰森 (或者泡菜,山药,随便什么……)args。

    • 但这个设置似乎有效
    • 我甚至可以派 datetime 对象(即 start 我在任务中使用的属性,用于将存储的子项与通过API发送的新值进行匹配)。

    那这里发生了什么?

    • 一切正常吗,芹菜序列化和反序列化命令像一个老板。
    • 或者我疯了,应该在调用任务和反序列化任务之前序列化?

    [更新,添加芹菜设置]

    CELERY_BROKER_URL = get_env_variable('REDIS_URL')
    CELERY_BROKER_POOL_LIMIT = 0
    CELERY_REDIS_MAX_CONNECTIONS = 10
    CELERY_ACCEPT_CONTENT = ['application/json']
    CELERY_TASK_SERIALIZER = 'json'
    CELERY_TIMEZONE = 'Europe/London'
    
    2 回复  |  直到 7 年前
        1
  •  0
  •   schillingt    7 年前

    您正在使用pickle序列化器,该序列化器将相对较好地处理对象,但也存在一些问题。 Here's a blog post on the concept of serializing and celery.

        2
  •  0
  •   bak2trak    7 年前

    是的,你做得对。

    如中所述 doc .

    客户机和工作机之间传输的数据需要序列化,因此芹菜中的每个消息都有一个content_类型的头,描述用于对其进行编码的序列化方法。

    另外,芹菜4.0的默认序列化程序是json(它是 pickle 早些时候。因此,每当您调用此任务时,芹菜默认是序列化和反序列化它。 如果要使用任何其他序列化程序,则在调用任务时需要指定 content-type (如果您正在使用 .delay 那么默认情况下序列化程序将是 json .

    process_children.apply_async((model_id, children_data), serializer='pickle')
    
    推荐文章