How to fix “django.db.utils.ProgrammingError: relation ‘users_user’ does not exist” error when running python manage.py migrate_schemas --shared in a Django multi-tenant application?
I’m encountering the following error when trying to run migrations for the shared schema in my Django multi-tenant application:
django.db.utils.ProgrammingError: relation "users_user" does not exist
The error occurs when running:
python manage.py migrate_schemas --shared
My project structure includes:
- A custom User model in the
usersapp - Multi-tenant setup using django-tenants
- The following configuration in settings.py:
AUTH_USER_MODEL = 'users.User'
SHARED_APPS = [
'django_tenants',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms',
'crispy_bootstrap5',
'django_htmx',
'django_celery_beat',
'core',
'tenants',
]
TENANT_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users',
'accreditation',
'documents',
'checklists',
'notifications',
'reports',
'audit',
]
My User model is defined as:
from django.contrib.auth.models import AbstractUser
from django.db import models
class User(AbstractUser):
ROLE_CHOICES = [
('super_admin', 'Super Admin'),
('org_admin', 'Organization Admin'),
('dept_user', 'Department User'),
('auditor', 'Auditor'),
]
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='dept_user')
tenant = models.ForeignKey('tenants.Tenant', on_delete=models.CASCADE, null=True, blank=True)
phone = models.CharField(max_length=15, blank=True)
department = models.CharField(max_length=100, blank=True)
class Meta:
db_table = 'users_user'
The full error traceback shows the issue occurs during the migration process, specifically when trying to apply the admin.0001_initial migration. How can I resolve this migration error and ensure the users_user table is properly created in the shared schema?
The “django.db.utils.ProgrammingError: relation ‘users_user’ does not exist” error typically occurs when Django-tenants cannot find the custom user model table during migration of the shared schema. This happens because the migration process attempts to reference tables that haven’t been created yet due to incorrect app configuration or migration order.
Contents
- Understanding the Problem
- Root Causes of the Error
- Step-by-Step Solutions
- Prevention Strategies
- Alternative Approaches
- Conclusion
Understanding the Problem
The ProgrammingError: relation "users_user" does not exist occurs specifically when running python manage.py migrate_schemas --shared in a Django multi-tenant setup. This error indicates that the migration process is trying to access the users_user table before it has been created in the shared schema.
As one Reddit user explains, this is a common issue when using custom user models with django-tenants: “To fix this, add django.contrib.auth to the SHARED_APPS or TENANT_APPS that don’t have it. NOW HERES THE IMPORTANT PART. I’m pretty sure that after you do that, you’ll have to delete the schema and remigrate it back.”
The issue stems from the complex relationship between shared and tenant-specific schemas, where Django’s migration system needs to understand which tables belong to which schema and in what order they should be created.
Root Causes of the Error
Based on the research findings, several factors can contribute to this error:
-
Incorrect app configuration: The custom user model’s app may not be properly included in the right apps list (SHARED_APPS vs TENANT_APPS)
-
Migration order issues: Migrations are being applied in an order that references tables that don’t exist yet
-
Schema state problems: Existing schema state may be inconsistent with the current migration state
-
Missing dependencies: Required Django auth components may not be properly configured for multi-tenant operations
Step-by-Step Solutions
Solution 1: Correct App Configuration
The most common fix involves ensuring your apps configuration includes the necessary components in the correct locations. Based on the research findings:
- Add django.contrib.auth to SHARED_APPS:
SHARED_APPS = [
'django_tenants',
'django.contrib.admin',
'django.contrib.auth', # Ensure this is included
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'crispy_forms',
'crispy_bootstrap5',
'django_htmx',
'django_celery_beat',
'core',
'tenants',
'users', # Add your users app to SHARED_APPS
]
- Verify TENANT_APPS configuration:
TENANT_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'users', # Keep users in both if needed
'accreditation',
'documents',
'checklists',
'notifications',
'reports',
'audit',
]
Important: According to the research, after making these changes, “you’ll have to delete the schema and remigrate it back” to get the proper state.
Solution 2: Proper Migration Order
Follow this specific sequence to ensure migrations are applied in the correct order:
- Generate migrations for all apps first:
python manage.py makemigrations
python manage.py makemigrations users
python manage.py makemigrations tenants
python manage.py makemigrations core
- Migrate shared schema first:
python manage.py migrate_schemas --shared
- Then migrate individual schemas:
python manage.py migrate_schemas
As one user reported: “However I had to run make migrations for the apps users and tenants (where I have my django_tenant models) and then migrate worked perfectly.”
Solution 3: Schema Recreation
If the above solutions don’t work, you may need to recreate the schemas:
- Delete existing schemas (back up your data first!):
python manage.py flush_schemas
- Reset migrations (optional but sometimes necessary):
python manage.py migrate users zero
python manage.py migrate tenants zero
- Follow the proper migration sequence again:
python manage.py makemigrations python manage.py migrate_schemas --shared python manage.py migrate_schemas
Solution 4: Manual Migration Approach
For more complex scenarios, you may need to manually control the migration process:
- Create a custom migration command:
# in management/commands/migrate_schemas_safe.py
from django.core.management import call_command
from django_tenants.utils import tenant_context
class Command(BaseCommand):
def handle(self, *args, **options):
# Migrate shared schema first
call_command('migrate_schemas', '--shared', interactive=False)
# Then migrate individual schemas
call_command('migrate_schemas', interactive=False)
- Run the custom migration command:
python manage.py migrate_schemas_safe
Prevention Strategies
To avoid this error in the future:
-
Always include django.contrib.auth in SHARED_APPS when using custom user models
-
Run
makemigrationsbeforemigratein development environments -
Test migration sequences in a development environment before applying to production
-
Use version control to track migration files and ensure consistency across environments
-
Regularly backup your database before running migration operations
Alternative Approaches
If you continue to experience issues, consider these alternative approaches:
-
Use a different user model approach:
- Consider making your user model truly tenant-specific
- Or use a completely separate authentication system for the shared schema
-
Database-level solutions:
- Manually create the required tables before running migrations
- Use database views to abstract the schema differences
-
Consider alternative multi-tenant solutions:
- Evaluate if django-tenants is the right fit for your use case
- Explore other multi-tenant packages that might handle custom user models better
Conclusion
The “relation does not exist” error when running migrate_schemas --shared with custom user models in django-tenants is a common but solvable problem. The key solutions involve:
- Properly configuring your SHARED_APPS and TENANT_APPS to include all necessary components
- Following the correct migration sequence with proper
makemigrationssteps - Potentially recreating schemas after configuration changes
- Using manual migration approaches for complex scenarios
Remember that after making configuration changes, you’ll likely need to delete existing schemas and remigrate them as noted in the research findings. Always backup your database before performing migration operations, and test thoroughly in a development environment first.
Sources
- r/django on Reddit: Django_tenants + custom user model migration errors
- r/django on Reddit: Has anyone used django-tenant-schemas that can answer this question about users?
- Stack Overflow: Deploying a multi tenant application (django-tenant) - Error to run ./manage migrate_schemas
- Stack Overflow: multi tenant - django.db.utils.ProgrammingError: relation “users_user” does not exist
- GitHub Issue: Using django-tenant-schemas doesn’t apply my AUTH_USER_MODEL when running migrate_schema
- GitHub Issue: “tenants_client” does not exist when I run migrate schemas in django 3