Django RQ ModuleNotFoundError xxx is not a package

307 Views Asked by At

I'm using django rq for some long running task, which I would like to provide some feedback about its progress. I hence created a function which is enqueued as a new task and set some model's attribute and save them.

Here is a simplified view:

class Status(models.Model):
  progress_a = models.PositiveIntegerField(default=0)

class MyObject(models.Model):
    status = models.OneToOneField(Status)

    @django_rq.job('low-short')
    def set_status(self, progress_name, progress):
        setattr(self.status, progress_name, progress)
        self.status.save()

   def set_status_a(self, progress):
        self.set_status.delay(self=self, progress_name="progress_a", progress=progress)

@django_rq.job('default')
def long_running_job():
    my_instance.set_status_a(100)

Now, executing this give me the following output :

2022-05-16 15:50:03 app-85c8459c79-mrkhg rq.worker[1] INFO low-short: api.models.MyObject.set_status(progress=0, progress_name='progress_a', self=<MyObject: MyObject object (129)>) (c13480ca-a25b-4463-af9a-a0a0dd67de61)
2022-05-16 15:50:03 app-85c8459c79-mrkhg root[41] WARNING Import error for 'api.models.MyObject'
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/site-packages/rq/utils.py", line 141, in import_attribute
    module = importlib.import_module(module_name)
  File "/usr/local/lib/python3.9/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1030, in _gcd_import
  File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
  File "<frozen importlib._bootstrap>", line 981, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'api.models.MyObject'; 'api.models' is not a package
  • api is a package
  • api.models a module
  • models.MyObject a class.

I don't get why it doesn't work. What am I doing wrong ? long_running_job starts as a job flawlessly.

Note: when removing self=self, it complains about missing self.

Update

Here is the workaround I use to make it work:

# The Method from the class call a simple function
def set_status_a(self, progress):
  set_status_a(obj_id=self.id, progress_name="progress_a", progress=progress)
# set_status_a call another function as a job
def set_status_a(obj_id, progress):
    _set_status_a(obj_id, progress)
# _set_status_a make the change by retrieving the object
@django_rq.job('default')
def _set_status_a(obj_id, progress):
    my_obj = MyObject.objects.get(id=obj_id)
    my_obj.status = progress
    my_obj.save()
0

There are 0 best solutions below