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 set
s 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.