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

Boolean values can be stored and fetched if the field type is str and not bool using aredis. #352

Closed
wiseaidev opened this issue Aug 16, 2022 · 5 comments

Comments

@wiseaidev
Copy link
Contributor

Hey everyone, I am trying to store and fetch in a model whose field's type is boolean. However, as you may know, Redis will complain about that when trying to encode bool values. But, I found a workaround for this use case, take the following as an example using the sync version redis_om:

from typing import Optional

from redis_om import Field, HashModel, JsonModel, Migrator


class Author(HashModel):
    first_name: str = Field(index=True)
    last_name: str
    active: Optional[bool] = Field(index=True, default=False)


class Blog(JsonModel):
    title: str = Field(index=True, full_text_search=True)
    content: str
    author: Author


Migrator().run()


author = Author(
    first_name="Mahmoud",
    last_name="Harmouch",
).save()

blog = Blog(
    title="Redis",
    content="Redis is a blazingly fast k/v store!",
    author=author
)


blog.save()

print(blog.pk)

assert Blog.find(Blog.pk == blog.pk).all()) == blog

Running this above script will throw the following exception:

redis.exceptions.DataError: Invalid input of type: 'bool'. Convert to a bytes, string, int or float first.

However, if you are using the async version, storing and indexing will work if the type is str. So to make boolean values work in aredis_om, just replace str in place of bool:

class Author(HashModel):
    first_name: str = Field(index=True)
    last_name: str
    active: Optional[str] = Field(index=True, default=False)


class Blog(JsonModel):
    title: str
    content: str
    author: Author = Field(index=True)

And your endpoints call async functions like the following to create/fetch k/v:

async def get_blogs(author: Optional[Author] = None):
    if not author:
        return await Author.find().all()
    else:
        return await Author.find(Author.author == author).all()

async def create_author(request: Request):
    return await Author(first_name=request.first_name, last_name=request.last_name, active=request.active).save()
    # or simply: return await Author(**request).save() if request is a dict.

Just wanted to share in case someone might find it helpful.

@Brandon-lz
Copy link

thanks for you sharing, it is very useful, and I filtered the data in the following way::

await Author.find(Author.active== 'False').all()

@sav-norem
Copy link

Great find! @simonprickett this seems also like a documentation issue

@llirrikk
Copy link

@sav-norem, this isn't documentation issue. In #193 he said:

Hi there - boolean fields aren't yet supported for JSON or Hash, they'll likely appear in JSON first as boolean is a native type there vs a Redis Hash that understands strings, floats and ints.

@sav-norem
Copy link

@llirrikk - Sure! I meant more like we can label this as a documentation issue since it provides documentation and isn't raising a new bug type of issue that needs a new PR to fix.

@slorello89
Copy link
Member

should be resolved by #611, so going to go ahead and close this out.

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

No branches or pull requests

5 participants