rq / django-rq

A simple app that provides django integration for RQ (Redis Queue)
MIT License
1.82k stars 286 forks source link

KeyError accessing stats page #632

Closed bennylope closed 9 months ago

bennylope commented 10 months ago

The Redis database does not need to be declared in the Redis connection string, allowing the default 0 db to be used. This is what many providers do when providing a connection string, e.g. Heroku, Render, etc. If using an existing Redis cache connection as described in the readme, no DB will ever be included.

The connection uses db 0 but the connection kwargs do not reflect this, and the get_scheduler_statistics() function depends on the connection kwargs.

https://github.com/rq/django-rq/blob/7c7fb632b4eaa6faa5930a1b93d408a1db4820ce/django_rq/utils.py#L97-L105

When the db is not included in the connection kwargs (line 105 above), a KeyError is raised.

csilcock commented 10 months ago

This is blocking our team from upgrading to django-rq 2.9.x - any idea when the fix will be merged / released?

bennylope commented 10 months ago

@csilcock there is a workaround and I feel badly for forgetting to share it.

Add this function somewhere - I chose to add it to a separate module to import into settings:

from urllib.parse import urlparse

def redis_with_default_db(redis_url):
    """Return a redis connection with the specified db.

    Necessary to ensure that the DB is in the connection kwargs.
    """
    parsed = urlparse(redis_url)
    db = parsed.path.strip("/") or "0"
    return parsed._replace(path=f"/{db}").geturl()

Then in your settings.py file (having either imported redis_with_default_db or defined it locally):

REDIS_URL = redis_with_default_db(os.environ.get("REDIS_URL", "redis://"))

This is not guaranteed to work universally, but the general concept could be reapplied if the connection string differs.