Update a MongoEngine document using a python dict?

前端 未结 6 1149
我在风中等你
我在风中等你 2021-02-05 18:24

Is it possible to update a MongoEngine document using a python dict?

For example:

class Pets(EmbeddedDocument):
    name = StringField()

class Person(Do         


        
6条回答
  •  南旧
    南旧 (楼主)
    2021-02-05 18:48

    I have tried most of the answers above, none of them seem really work with Embedded documents. Even though the they updated the fields they did also deleted content of unfilled fields in Embedded document.

    For that I decided to take a path suggested by @hckjck, I have written a simple function that converts dict to a format so it can be processed by document.update:

    def convert_dict_to_update(dictionary, roots=None, return_dict=None):
        """    
        :param dictionary: dictionary with update parameters
        :param roots: roots of nested documents - used for recursion
        :param return_dict: used for recursion
        :return: new dict
        """
        if return_dict is None:
            return_dict = {}
        if roots is None:
            roots = []
    
        for key, value in dictionary.iteritems():
            if isinstance(value, dict):
                roots.append(key)
                convert_dict_to_update(value, roots=roots, return_dict=return_dict)
                roots.remove(key)  # go one level down in the recursion
            else:
                if roots:
                    set_key_name = 'set__{roots}__{key}'.format(
                        roots='__'.join(roots), key=key)
                else:
                    set_key_name = 'set__{key}'.format(key=key)
                return_dict[set_key_name] = value
    
        return return_dict
    

    Now this data:

    {u'communication': {u'mobile_phone': u'2323232323', 'email':{'primary' : 'email@example.com'}}}
    

    will be converted to:

    {'set__communication__mobile_phone': u'2323232323', 'set__communication__email__primary': 'email@example.com'}
    

    Which can be used like this

    document.update(**conv_dict_to_update(data))
    

    Also available in this gist: https://gist.github.com/Visgean/e536e466207bf439983a

    I don't know how effective this is but it works.

提交回复
热议问题