Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dict field can't handle python's Decimal #707

Open
ivan-kleshnin opened this issue Jul 16, 2014 · 15 comments
Open

Dict field can't handle python's Decimal #707

ivan-kleshnin opened this issue Jul 16, 2014 · 15 comments

Comments

@ivan-kleshnin
Copy link

Attempt to save decimal.Decimal object as one of the values in DictField raises bson.errors.InvalidDocument: Cannot encode object: Decimal('20000')

@ivan-kleshnin ivan-kleshnin changed the title Dict field can not contain python Decimal's Dict field can not handle python Decimal's Jul 16, 2014
@ivan-kleshnin ivan-kleshnin changed the title Dict field can not handle python Decimal's Dict field can't handle python Decimal's Jul 16, 2014
@ivan-kleshnin ivan-kleshnin changed the title Dict field can't handle python Decimal's Dict field can't handle python's Decimal Jul 16, 2014
@thedrow thedrow added the bug label Jul 26, 2014
@thedrow
Copy link
Contributor

thedrow commented Jul 26, 2014

I'm not sure if bson can serialize Decimal objects.
We definitely need to solve this.
Care to provide a failing test case?

@thedrow thedrow added this to the Needs More Information milestone Jul 26, 2014
@lig
Copy link
Contributor

lig commented Nov 25, 2014

Python Decimal should be saved via MongoEngine DecimalField. By the way DecimalField it self looks unusable see #637.

@thedrow
Copy link
Contributor

thedrow commented Nov 25, 2014

@lig Is this a duplicate then?

@ivan-kleshnin
Copy link
Author

It's not a duplicate. DictField should handle python Decimal's somehow as they are native Python objects. Arguing about DecimalField is an offtopic remark. I'm no longer interested in MongoEngine and Mongo (and Python)... just my final note here.

@lig
Copy link
Contributor

lig commented Nov 25, 2014

@thedrow First of all it is very hard to understand DictField behavior basing on documentation. Too few words there: https://mongoengine-odm.readthedocs.org/en/latest/apireference.html#mongoengine.fields.DictField

In favor of 0.9 I would say that we should plan for next release:

  1. Enhance DictField documentation in sense of "handle complex / varying types of data". What that types are, how are they handled.
  2. Ensure DictField is able to handle any type that could be handled by scalar fields automatically.
  3. Ensure that other free form fields like ListField, DynamicDocument, DynamicField, etc are able to do the same.

As for now I think we should record this as known issue as it is very specific case that could be easily worked around.

@ivan-kleshnin
Copy link
Author

It can't be easily worked around because DictField with any nested field and DocumentField with nested DecimalField bring different semanthics and different limitations considering other existing issues with default values and so on which I wouldn't like to recall. Just remember it was a mess to workaround.

@lig
Copy link
Contributor

lig commented Nov 26, 2014

Well you are always able to check deep into dict values before saving and
convert buggy values to something you will be able to restore them from on
load.

It could be done using custom Field around DictField. This is just
straight forward coding that is not hard enough to support by hands.

On Wed, Nov 26, 2014 at 2:39 PM, Ivan Kleshnin [email protected]
wrote:

It can't be easily worked around because DictField with any nested field
and DocumentField with nested DecimalField bring different semanthics and
different limitations considering other existing issues with default values
and so on which I wouldn't like to recall. Just remember it was a mess to
workaround.


Reply to this email directly or view it on GitHub
#707 (comment)
.

Serge Matveenko
mailto: [email protected]
github: http://lnkfy.com/1
linkedin: http://lnkfy.com/S

@DavidBord
Copy link
Contributor

A test that reproduces it:

    class Doc(Document):
        keyval = DictField()
    Doc(keyval={"dec": Decimal(20000)}).save()

@DavidBord
Copy link
Contributor

@thedrow, are you sure we want to solve this? indeed, bson shouldn't serialize Decimal objects so why should we coerce it?

@thedrow
Copy link
Contributor

thedrow commented Jan 18, 2015

Because as a framework we should be able to deal with Python data types that are being saved to mongo.

@DavidBord
Copy link
Contributor

Lets say we'll represent stuff like Decimal(3.14) as strings. What would we do with the aggregation framework?

@thedrow
Copy link
Contributor

thedrow commented Jan 26, 2015

That's a very good question.
There are some suggestions on StackOverflow on how to represent decimals in MongoDB.

@thedrow
Copy link
Contributor

thedrow commented Jan 26, 2015

Here's how eBay does it and you can't say they are not using decimals and aggregations.

@wojcikstefan
Copy link
Member

wojcikstefan commented Mar 4, 2017

Starting with MongoDB v3.4, you can use the Decimal BSON Type.

@carlos-jenkins
Copy link

For anyone looking for a quick answer:

from bson.decimal128 import Decimal128

for key in ['decimal_key1', 'decimal_key2']:
    row[key] = Decimal128(row[key])

You need to convert the Decimal to BSON's Decimal128 before inserting to the database. More info:

https://api.mongodb.com/python/current/api/bson/decimal128.html#module-bson.decimal128

You also require MongoDB 3.4+.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants