My Django project (python==3.10.3, Django==4.0.4) is accessing an MSSQL server via pymssql (pymssql==2.2.5), scraping what I need, and getting a list of dicts. I then save to MongoDB (pymongo==4.2.0) but there are decimal values that need to be Decimal128. I found Pymongo: Cannot encode object of type decimal.Decimal? which has a similar goal as mine. So I adapted to handle the list of dict like this:
def convert_decimal_iterdict(list_of_dict):
if list_of_dict is None:
return None
for i in list_of_dict:
for k, v in i.items():
if isinstance(v, dict):
convert_decimal_iterdict(v)
elif isinstance(v, list):
for l in v:
convert_decimal_iterdict(l)
elif isinstance(v, Decimal):
list_of_dict[k] = Decimal128(str(v))
return list_of_dict
It errors with
list_of_dict[k] = Decimal128(str(v))
TypeError: list indices must be integers or slices, not str
So I attempted to use Decimal, float, or int...
list_of_dict[k] = Decimal128(Decimal(v))
but get
#Decimal
raise TypeError("Cannot convert %r to Decimal128" % (value,))
TypeError: Cannot convert 1 to Decimal128
#float
raise TypeError("Cannot convert %r to Decimal128" % (value,))
TypeError: Cannot convert 1.0 to Decimal128
#int
raise TypeError("Cannot convert %r to Decimal128" % (value,))
TypeError: Cannot convert 1 to Decimal128
removing altogether
list_of_dict[k] = Decimal128(v)
just gives the original 'not str' TypeError:
I'm sure it's something easy that i'm just not seeing. I know you can't
CodePudding user response:
Let's take a closer look at the line at which an error is being raised:
list_of_dict[k] = Decimal128(str(v))
list_of_dict
is a list, k
is a key from one of the dict
s. From your error message, k
is evidently a string. If you're indexing a list, you should be using list indexes, not dict
keys.
What you seem to want to do is to convert a single decimal value in one of the dict
s to Decimal128. The current dict
you are iterating through is in the variable i
, so try changing the line above to this:
i[k] = Decimal128(str(v))
(You might also want to consider improving the name of the variable i
, both to make it more descriptive, and also because i
, j
, k
etc. are often used as loop counter variables containing integer values.)
Finally, I must state that this code hasn't been tested. I don't have a copy of MongoDB installed.