How to clear Django RQ jobs from a queue?

8.9k Views Asked by At

I feel a bit stupid for asking, but it doesn't appear to be in the documentation for RQ. I have a 'failed' queue with thousands of items in it and I want to clear it using the Django admin interface. The admin interface lists them and allows me to delete and re-queue them individually but I can't believe that I have to dive into the django shell to do it in bulk.

What have I missed?

6

There are 6 best solutions below

0
On

The other answers are outdated with the RQ updates implementing Registries.

Now, you need to do this to loop through and delete failed jobs. This would work any particular Registry as well.

import django_rq
from rq.registry import FailedJobRegistry

failed_registry = FailedJobRegistry('default', connection=django_rq.get_connection())

for job_id in failed_registry.get_job_ids():
    try:
        failed_registry.remove(job_id, delete_job=True)
    except:
        # failed jobs expire in the queue. There's a
        # chance this will raise NoSuchJobError
        pass

Source

0
On

You can empty a queue from the command line with:

rq empty [queue-name]

Running rq info will list all the queues.

0
On

You can empty any queue by name using following code sample:

import django_rq

queue = "default"
q = django_rq.get_queue(queue)
q.empty()

or even have Django Command for that:

import django_rq

from django.core.management.base import BaseCommand


class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument("-q", "--queue", type=str)

    def handle(self, *args, **options):
        q = django_rq.get_queue(options.get("queue"))
        q.empty()

4
On

The redis-cli allows FLUSHDB, great for my local environment as I generate a bizzallion jobs.

With a working Django integration I will update. Just adding $0.02.

5
On

The Queue class has an empty() method that can be accessed like:

import django_rq
q = django_rq.get_failed_queue()
q.empty()

However, in my tests, that only cleared the failed list key in Redis, not the job keys itself. So your thousands of jobs would still occupy Redis memory. To prevent that from happening, you must remove the jobs individually:

import django_rq
q = django_rq.get_failed_queue()
while True:
    job = q.dequeue()
    if not job:
        break
    job.delete()  # Will delete key from Redis

As for having a button in the admin interface, you'd have to change django-rq/templates/django-rq/jobs.html template, who extends admin/base_site.html, and doesn't seem to give any room for customizing.

0
On

As @augusto-men method seems not to work anymore, here is another solution:

You can use the the raw connection to delete the failed jobs. Just iterate over rq:job keys and check the job status.

from django_rq import get_connection
from rq.job import Job

# delete failed jobs
con = get_connection('default')
for key in con.keys('rq:job:*'):
    job_id = key.decode().replace('rq:job:', '')
    job = Job.fetch(job_id, connection=con)
    if job.get_status() == 'failed':
        con.delete(key)
con.delete('rq:failed:default')  # reset failed jobs registry