Package: django-tenant-schemas-q
Django Tenant Schemas QDjango Tenant Schemas Q is a custom implementation for Django-Q cluster for projects that make use Django Tenant Schemas package to achieve multi-tenancy in their Django projects with Postgres as database service. Using this package, developer can setup a Django project to be multi-tenant and setup Django-Q cluster to work per tenant/schema basis. This package works with any other broker apart from Django ORM.Why the need for this package?Although there is packagetenant-schemas-celerysupporting celery for multi-tenancy, I was quite intrigued by thedjango-qproject and was exploring the possibility of makingdjango-qwork withdjango-tenant-schemas.Installationpip install django-tenant-schemas-qThis should installdjango-tenant-schemasanddjango-q.How to set this up?As a developer I often find that setting up projects, packages and getting configurations right is sometimes a relatively tough job. In order to make this work nicely, just follow the steps below.Refer to settings required bydjango_tenant_schemasmentionedhereSetupdjango_tenant_schemasas per the instructions in the above mentioned link. This will take care of setting up ofdjango_tenant_schemas.Adddjango_qto TENANT_APPS setting. This will setup models like Task, Schedule on every tenant post migrations.Follow it up with setting up the Django-Q cluster that needs to be run in order to process tasks and run our scheduler.While setting up configuration for cluster,make use of any other broker supported by Django-Q apart from Django ORM.Finally add a settingSCHEMAS_TO_BE_EXCLUDED_BY_SCHEDULERin your settings file. The value for this setting is a list of schema that you wish to exclude from scheduler, If not specified, scheduler will exclude a schema by namepublicby default.How will this workAssuming you have followed the instructions perfectly, you should now have settings looking likeSHARED_APPS = ['tenant_schemas', 'app_containing_tenant_model ', 'any_other_app_needed']TENANT_APPS = ['django_q', 'standard_django_apps', 'any_other_app_needed']INSTALLED_APPS = ['tenant_schemas', 'app_containing_tenant_model', 'django_q', 'standard_django_apps', 'any_other_app_needed']TENANT_MODEL = 'app_name.ModelName'SCHEMAS_TO_BE_EXCLUDED_BY_SCHEDULER = ['public']Q_CLUSTER = {} # Configuration for Q ClusterWhat these settings will do is simple. It will simply createTask & Schedulemodels per schema. Django-Q uses these modules to store the tasks and schedules. With these models now setup on per schema/tenant basis the things become a bit cleaner.To run the cluster, use the commandpython manage.py msclusterOnce the command is fired, the cluster will start and accept the tasks and schedules.Now, given that are schedules are tasks that are executed as per the frequency having them per schema/tenant basis is something that I wanted to achieve. This would give me ability to configure same tasks with different times and the system will work as expected.How to use itTo allow adding a task or schedule with database schema awareness, package contains utilities to make it is seamless.Add the linefrom django_tenant_schemas_q.utils import QUtilitiesto the line from where you wish to add ataskor ascheduleTo add an async task you can useQUtilities.add_async_task(func_name_as_string, *args, **kwargs)You can addsync=Truein kwargs to run the task synchronously.To create a new schedule you can useQUtilities.create_schedule(func_name_as_string, *args, **kwargs)To get a result of a single taskQUtilities.get_result(task_id, wait=0, cached=Conf.CACHED)To get a result of a groupQUtilities.get_result_group(group_id, failures=False, wait=0, count=None, cached=Conf.CACHED)To fetch a single taskQUtilities.fetch_task(task_id, wait=0, cached=Conf.CACHED)To fetch a group of tasksQUtilities.fetch_task_group(group_id, failures=True, wait=0, count=None, cached=Conf.CACHED)To get count of groupsQUtilities.get_group_count(group_id, failures=False, cached=Conf.CACHED)To delete a group of tasksQUtilities.delete_task_group(group_id, tasks=False, cached=Conf.CACHED)To delete a task from cacheQUtilities.delete_task_from_cache(task_id, broker=None)To get the size of the queueQUtilities.get_queue_size(broker=None)To add multiple async tasks using IterQUtilities.add_async_tasks_from_iter(func, args_iter, **kwargs)For this useIterfromdjango_tenant_schemas_q.custommodule.To create a chain of tasks using ChainQUtilities.create_async_tasks_chain(chain, group=None, cached=Conf.CACHED, sync=Conf.SYNC, broker=None)For this useChainfromdjango_tenant_schemas_q.custommodule.Test the projectThere is a test django project in the repository.Clone the repositoryRundocker-compose -f test-compose.yml buildRundocker-compose -f test-compose.yml up -dRundocker-compose -f test-compose.yml run backend python manage.py setupdataRundocker-compose -f test-compose.yml run backend python manage.py test --keepdbFull credit to authorshttps://github.com/Koed00of Django-Q andhttps://github.com/bernardopiresof Django-Tenant-Schemas for two wonderful packages.