redis / redis-om-python

Object mapping, and more, for Redis and Python
MIT License
1.12k stars 112 forks source link

JsonModel is not working when Redis require password #410

Closed yanbo-huang closed 1 year ago

yanbo-huang commented 1 year ago

My environment and settings

Tool/library versions:

My configurations:

...


- redis connection string in my Python application

REDIS_OM_URL=redis://:fakepass@localhost:6379/0


### Issue

TLDR; 

> `JsonModel` cannot run query if the password in `Redis` is enabled.

I created a `JsonModel` called `MyUser`. 

```python
from redis_om import Field, JsonModel, Migrator, get_redis_connection
...

class MyUser(JsonModel):
    """
    My redis model
    """

    user_id: str = Field(index=True)
    user_session_id: int
    name: str
    scopes: list[str]
    other_info: set[tuple[str, str]]

MyUser.Meta.database = get_redis_connection(
    url=settings.REDIS_OM_URL, decode_responses=True
)
Migrator().run()

When you run any query like MyUser.find(MyUser.user_id == some_user_id), it will throw exception:

    ...
  File ".../python3.10/site-packages/redis_om/model/model.py", line 1212, in find
    return FindQuery(expressions=expressions, model=cls)
  File ".../lib/python3.10/site-packages/redis_om/model/model.py", line 350, in __init__
    if not has_redisearch(model.db()):
  File ".../lib/python3.10/site-packages/redis_om/checks.py", line 25, in has_redisearch
    if has_redis_json(conn):
  File ".../lib/python3.10/site-packages/redis_om/checks.py", line 17, in has_redis_json
    command_exists = check_for_command(conn, "json.set")
  File ".../lib/python3.10/site-packages/redis_om/checks.py", line 9, in check_for_command
    cmd_info = conn.execute_command("command", "info", cmd)
  File ".../lib/python3.10/site-packages/redis/client.py", line 1238, in execute_command
    return conn.retry.call_with_retry(
  File ".../lib/python3.10/site-packages/redis/retry.py", line 46, in call_with_retry
    return do()
  File ".../lib/python3.10/site-packages/redis/client.py", line 1239, in <lambda>
    lambda: self._send_command_parse_response(
  File ".../lib/python3.10/site-packages/redis/client.py", line 1215, in _send_command_parse_response
    return self.parse_response(conn, command_name, **options)
  File ".../lib/python3.10/site-packages/redis/client.py", line 1260, in parse_response
    return self.response_callbacks[command_name](response, **options)
  File ".../lib/python3.10/site-packages/redis/client.py", line 550, in parse_command
    cmd_name = str_if_bytes(command[0])
TypeError: 'NoneType' object is not subscriptable

It failed internally when trying to check whether you have RedisJson and parse the command response, while it gets None as response.

The find query is working fine if the redis-stack doesn't set the requirepass and set REDIS_OM_URL purely as redis://@localhost:6379/0.

Any idea on how to solve this issue? It seems like this is a bug in the library when it run has_redisearch checking.

yanbo-huang commented 1 year ago

All right. I just found out that for Redis-Stack server, the correct starting command is redis-stack-server ... instead of redis-server .... I think that's why the has-redis-json checks got no response.

So the solution is to change the entrypoint in the docker-compose from command: redis-server --requirepass fakepass to command: redis-stack-server --requirepass fakepass.

The issue can be closed.