rethinkdb-python icon indicating copy to clipboard operation
rethinkdb-python copied to clipboard

RethinkDB converts float 0.0 to int 0

Open EugeniuZ opened this issue 4 years ago • 3 comments

Hi,

Seems that RethinkDB is converting float value of 0.0 to integer value of 0. In my scenario the problem is that python dictionaries are saved in RethinkDB and upon retrieval this (undesired) conversion happens. Some of the upstream systems check for the type of the field (float is expected but an int is received).

Is there a way to avoid this conversion? Is it a feature or a bug?

task_info = {'a': 0.0, 'b': +0.0, 'c': -0.0}
ta = task_info['a']
tb = task_info['b']
tc = task_info['c']
print(f'ta - {type(ta)}, {ta}')
print(f'tb - {type(tb)}, {tb}')
print(f'tc - {type(tc)}, {tc}')
result = r.table(table).insert(task_info).run(connection)
task_id = result['generated_keys'][0]

Output is:

ta - <class 'float'>, 0.0
tb - <class 'float'>, 0.0
tc - <class 'float'>, -0.0
document = r.table(table).get(task_id).run(connection)
print(document)
a = document['a']
b = document['b']
c = document['c']
print(f'a - {type(a)}, {a}')
print(f'b - {type(b)}, {b}')
print(f'b - {type(c)}, {c}')

Output is:

{'a': 0, 'b': 0, 'c': -0.0, 'id': 'd8df59a5-330f-4cd0-84ac-394b70a05b9d'}
a - <class 'int'>, 0
b - <class 'int'>, 0
b - <class 'float'>, -0.0

Using the latest container (rethinkdb 2.4.1~0buster) Python client version (rethinkdb==2.4.8)

EugeniuZ avatar Sep 02 '21 15:09 EugeniuZ

You could enforce type, instead of relying on implicit type conversion.

a = foat(document['a']) b = float(document['b']) c = float(document['c'])

https://www.geeksforgeeks.org/type-conversion-python/

On Thu, Sep 2, 2021, 22:30 Eugeniu @.***> wrote:

Hi,

Seems that RethinkDB is converting float value of 0.0 to integer value of 0. In my scenario the problem is that python dictionaries are saved in RethinkDB and upon retrieval this (undesired) conversion happens. Some of the upstream systems check for the type of the field (float is expected but an int is received).

Is there a way to avoid this conversion? Is it a feature or a bug?

task_info = {'a': 0.0, 'b': +0.0, 'c': -0.0}ta = task_info['a']tb = task_info['b']tc = task_info['c']print(f'ta - {type(ta)}, {ta}')print(f'tb - {type(tb)}, {tb}')print(f'tc - {type(tc)}, {tc}')result = r.table(table).insert(task_info).run(connection)task_id = result['generated_keys'][0]

Output is:

ta - <class 'float'>, 0.0 tb - <class 'float'>, 0.0 tc - <class 'float'>, -0.0

document = r.table(table).get(task_id).run(connection)print(document)a = document['a']b = document['b']c = document['c']print(f'a - {type(a)}, {a}')print(f'b - {type(b)}, {b}')print(f'b - {type(c)}, {c}')

Output is:

{'a': 0, 'b': 0, 'c': -0.0, 'id': 'd8df59a5-330f-4cd0-84ac-394b70a05b9d'} a - <class 'int'>, 0 b - <class 'int'>, 0 b - <class 'float'>, -0.0

Using the latest container (rethinkdb 2.4.1~0buster) Python client version (rethinkdb==2.4.8)

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/rethinkdb/rethinkdb/issues/6984, or unsubscribe https://github.com/notifications/unsubscribe-auth/AA2NFALJZCLIDGXOBBW3FFLT76KBVANCNFSM5DJMKIRA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

sefgit avatar Sep 02 '21 23:09 sefgit

This is a behavior of the Python driver, not RethinkDB itself, which only has one numeric type, finite 64-bit floats.

I think the related code is here:

https://github.com/rethinkdb/rethinkdb-python/blob/master/rethinkdb/ast.py#L780

and that this behavior is a result of JSONDecoder: https://docs.python.org/3/library/json.html#json.JSONDecoder

There is no way to avoid this behavior. I don't think it's a bug. I'd describe the behavior as a decision rather than a feature.

srh avatar Sep 03 '21 00:09 srh

Hi @srh ,

If i try conversion to an from a string i get this result:

>>> task_info
{'a': 0.0, 'b': 0.0, 'c': -0.0}
>>> s = json.dumps(task_info)
>>> s
'{"a": 0.0, "b": 0.0, "c": -0.0}'
>>> json.loads(s)
{'a': 0.0, 'b': 0.0, 'c': -0.0}

@sefgit - the code handling the python dictionaries doesn't make any assumption about the structure of received the documents (which can have various levels of nesting) so using explicit conversion would require to make assumptions about the structure and data types of the fields in received documents.

EugeniuZ avatar Sep 03 '21 05:09 EugeniuZ