You can quickly build a multi-tenant site in Django with the help of this nifty package django-tenant-schemas. It works by assigning each tenant into its own database schema and having one public
schema for anything that needs to be shared.
It wraps Django's connection
with its own wrapper that help to route connection request accordingly based on the hostname tenant1.domain.com
to schema tenant1
. So this works great when you're in the context of Django application.
I have Celery task that needs to be run and needs to access the database. I could just pass the model directly to the Celery task params but it is not advisable to do so.
In my views.py
:
class StandardReport(APIView):
def get(self, request, format=None):
site = Site.objects.first()
run_report.delay(site.id)
return Response(site.name)
and in my tasks.py
, I have
@shared_task
def run_report(title, site_id):
# we need this
# c = connection.cursor()
# c.db.set_schema('myschema')
site = Site.objects.get(pk=site_id)
return site.name
If I don't have the commented lines, it won't work because it is hitting public
schema and the tables do not exist in public
schema.
Note: We can use set_schema
because that was the function available in the wrapper that was used internally by the package to handle switching of the schema.