Home > Net >  Python MongoDB save dictionary of sets
Python MongoDB save dictionary of sets

Time:12-22

I have a dictionary of sets that I want to save persistently in the mongodb database. However, I receive the error "Cannot encode object: {1, 2}, of type: <class 'set'>" in the process of saving. I saw a post where one user's suggestion was to save each set as a dict but that didn't seem like a good solution to me. Is there any other way, other than transforming each set into a list, of saving the dictionary with sets? The dictionary looks something like the following code but more complex and with thousands of entries with a string key and set() values:

{'One': {1, 2}, 'Two': {3, 4}, 'Three': {5, 6}}

CodePudding user response:

MongoDB used to have SONManipulators to transform documents going in and coming out of the DB but they were deprecated in 4.0 .. so you have to preprocess your sets into objects for saving and restore them on load.

Example:

test = {'One': {1, 2}, 'Two': {3, 4}, 'Three': {5, 6}}

def unsetify(doc):
    for k, v in doc.items():
        if isinstance(v, dict):
            doc[k] = unsetify(v)
        elif isinstance(v, set):
            doc[k] = { '_type': 'set', '_val': list(v) }
    return doc


def resetify(doc):
    for k, v in doc.items():
        if isinstance(v, dict):
            if v.get('_type', '') == 'set':
                doc[k] = set(v['_val'])
            else:
                doc[k] = resetify(v)
    return doc

doc = unsetify(test)
print(doc)
print(resetify(doc))

Output:

{'One': {'_type': 'set', '_val': [1, 2]}, 'Two': {'_type': 'set', '_val': [3, 4]}, 'Three': {'_type': 'set', '_val': [5, 6]}}
{'One': {1, 2}, 'Two': {3, 4}, 'Three': {5, 6}}

Yes it's recursive and yes it clobbers the input document in-place instead of making a copy etc. May not be ideal for the exact use case (can't say without more info) but demonstrates the principle.

  • Related