msiemens / tinydb

TinyDB is a lightweight document oriented database optimized for your happiness :)
https://tinydb.readthedocs.org
MIT License
6.84k stars 550 forks source link

convert type before matching in query #485

Closed LeiYangGH closed 2 years ago

LeiYangGH commented 2 years ago

I have a field foo which type sometimes are int, but sometimes are string(of numbers). If I compare directly, I will get error such as

TypeError: '<=' not supported between instances of 'int' and 'str'

I tried convert to int, int(q.foo) <= given_int but got

TypeError: int() argument must be a string, a bytes-like object or a number, not 'Query'

I searched document and found test function can determine the field type

        test_is_str = lambda s: isinstance(s, str)
       ...((q.foo.test(test_is_str)) & (q.foo <= str(given_int)))
        test_is_int = lambda s: not isinstance(s, str)
        ...((q.foo.test(test_is_int)) & (q.foo <= given_int))

But this way code seems too verbose, is there any simpler syntax to convert type before query?

msiemens commented 2 years ago

Hey @LeiYangGH,

I think you can use the map() query operator here:

db.search(where('num').map(int) > 0)

This assume that all num fields are numbers or strings that represent numbers. Otherwise, you can cast to a default value like NaN:

db.search(where('num').map(lambda x: int(x) if isinstance(x, int) or x.isnumeric() else float('nan')) > 0)

Does that work for you?

LeiYangGH commented 2 years ago

i think map works, thanks!

msiemens commented 2 years ago

Awesome 🙂